Computer graphics -- 2007-2008 -- info.uvt.ro/Laboratory 6
Quick links: front; laboratories agenda, 1, 2, 3, 4, 5, 6, 7, 8, evaluation, tools, repository.
Texture sphere mapping
editPlease consult Computer graphics -- 2007-2008 -- info.uvt.ro/Laboratory 5#Mapping a texture onto a sphere.
Texture blending and transparency
editDiscussion points
edit- what is blending;
- what is transparency (alpha testing);
Steps for blending
edit- enabling blending -- gl.glEnable(GL.GL_BLEND);
- setting the blend function -- gl.glBlendFunc(mode, mode);
- drawing the object(s);
- disabling blending -- gl.glDisable(GL.GL_BLEND);
- extra: there are cases when you need to disable the depth test while blending, by using the glEnable(GL_DEPTH_TEST) and glDisable(GL_DEPTH_TEST);
Steps transparency (alpha testing)
edit- enabling alpha testing -- glEnable(GL_ALPHA_TEST);
- setting alpha testing -- glAlphaFunc(GL_GREATER, 0.7f) -- discards the pixels with an alpha value less then 0.7 (for example);
References
edit- OpenGL Programming Guide -- Blending, Antialiasing, Fog, and Polygon Offset;
- NeHe blending and transparency;
- OpenGL FAQ -- Transparency, Translucency, and Blending;
- glBlendFunc;
Example
editThe following code can be found in the SVN repository, in the examples folder as example-09.
The following code simulates the Earth and its atmosphere by drawing two spheres with the same center but having different radices.
[...]
public void init(GLAutoDrawable canvas)
{
GL gl = canvas.getGL();
this.glu = new GLU();
this.glut = new GLUT();
gl.glClearColor(0, 0, 0, 0);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_NICEST);
gl.glShadeModel(GL.GL_SMOOTH);
try {
this.texture1 = TextureIO.newTexture (new File("./data/ground.jpeg"), true);
this.texture2 = TextureIO.newTexture (new File("./data/clouds.jpeg"), true);
} catch (IOException exception) {
exception.printStackTrace();
System.exit(1);
}
this.texture1.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
this.texture2.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
}
[...]
public void displayChanged(GLAutoDrawable canvas, boolean modeChanged, boolean deviceChanged)
{
return;
}
public void display(GLAutoDrawable canvas)
{
GL gl = canvas.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
gl.glPushMatrix();
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glDisable(GL.GL_BLEND);
gl.glPushMatrix();
gl.glRotated(this.angle, 0, 1, 0);
gl.glRotated(90, 1, 0, 0);
this.texture1.bind();
GLUquadric ground = glu.gluNewQuadric();
glu.gluQuadricTexture(ground, true);
glu.gluSphere(ground, 0.5, 64, 64);
glu.gluDeleteQuadric(ground);
gl.glPopMatrix();
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_COLOR, GL.GL_DST_ALPHA);
gl.glPushMatrix();
gl.glRotated(-this.angle, 0, 1, 0);
gl.glRotated(90, 1, 0, 0);
this.texture2.bind();
GLUquadric clouds = glu.gluNewQuadric();
glu.gluQuadricTexture(clouds, true);
glu.gluSphere(clouds, 0.52, 64, 64);
glu.gluDeleteQuadric(clouds);
gl.glPopMatrix();
gl.glPopMatrix();
gl.glFlush();
this.angle += 3;
}
private double angle;
[...]
Billboards
editDiscussions points
edit- what is a billboard: 2D texture that always faces the camera;
- what is it used for:
- particles;
- 2D objects always facing towards us like trees, mountains, etc.;
- simulating 3D objects;
Steps for orienting the billboard towards the camera
edit- recompute the vertices based on the distance between the billboard and the camera;
- use the vertices to draw the quad;
References
editExample
editThe following code can be found in the SVN repository, in the examples folder as example-10.
[...]
public void display(GLAutoDrawable canvas)
{
GL gl = canvas.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
this.updateCoordinates();
gl.glPushMatrix();
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
gl.glEnable (GL.GL_TEXTURE_2D);
this.bbTexture.bind();
gl.glBegin(GL.GL_QUADS);
gl.glTexCoord2d(0, 1);
gl.glVertex3dv(this.bbV1, 0);
gl.glTexCoord2d(1, 1);
gl.glVertex3dv(this.bbV2, 0);
gl.glTexCoord2d(1, 0);
gl.glVertex3dv(this.bbV3, 0);
gl.glTexCoord2d(0, 0);
gl.glVertex3dv(this.bbV4, 0);
gl.glEnd();
gl.glPopMatrix();
gl.glFlush();
}
private void updateCoordinates()
{
this.bbAngle += this.bbAngleDirection * this.bbAngleSpeed;
if (this.bbAngle > 13)
this.bbAngleDirection = -1;
if (this.bbAngle < -13)
this.bbAngleDirection = 1;
this.bbDistance = 10;
this.bbCx = Math.cos(Math.toRadians(90 + this.bbAngle)) * this.bbDistance;
this.bbCy = 0;
this.bbCz = Math.sin(Math.toRadians(90 + this.bbAngle)) * this.bbDistance;
this.camCx = 0;
this.camCy = 0;
this.camCz = 0;
this.bbV1 = new double[] {this.bbCx - 1, this.bbCy - 1, this.bbCz};
this.bbV2 = new double[] {this.bbCx + 1, this.bbCy - 1, this.bbCz};
this.bbV3 = new double[] {this.bbCx + 1, this.bbCy + 1, this.bbCz};
this.bbV4 = new double[] {this.bbCx - 1, this.bbCy + 1, this.bbCz};
double deltaX = -1 * (this.bbCx - this.camCx);
double deltaY = -1 * (this.bbCy - this.camCy);
double deltaZ = -1 * (this.bbCz - this.camCz);
double alpha = Math.atan2(deltaZ, deltaX) - Math.PI / 2.0;
double beta = Math.atan2(deltaY, Math.sqrt(deltaX * deltaX + deltaZ * deltaZ));
this.bbV1 = this.rotate(this.bbV1, alpha, beta);
this.bbV2 = this.rotate(this.bbV2, alpha, beta);
this.bbV3 = this.rotate(this.bbV3, alpha, beta);
this.bbV4 = this.rotate(this.bbV4, alpha, beta);
}
public double[] rotate(double[] v, double alpha, double beta)
{
double y = v[1] * Math.cos(beta) + v[2] * Math.sin(beta);
double z = -v[1] * Math.sin(beta) + v[2] * Math.cos(beta);
double x = v[0] * Math.cos(alpha) - z * Math.sin(alpha);
z = v[0] * Math.sin(alpha) + z * Math.cos(alpha);
return new double [] {x, y, z};
}
private double camCx;
private double camCy;
private double camCz;
private double bbAngle = 0;
private double bbAngleDirection = 1;
private double bbAngleSpeed = 0.5;
private double bbDistance = 25;
private double bbCx;
private double bbCy;
private double bbCz;
private double bbDx;
private double bbDy;
private double bbDz;
private double[] bbV1;
private double[] bbV2;
private double[] bbV3;
private double[] bbV4;
[...]
Assignment
editThis is the sixth assignment, so please commit it to the folder assignment-06.
Modify your last solar system simulator in the following way:
- add textures to all spheres (search the net for planetary textures. For example: Google (Images): -> earth map);
- add clouds to Earth;
- make the Sun a billboard (search Google (Images) for an image with the Sun);