Computer graphics -- 2007-2008 -- info.uvt.ro/Laboratory 6

From Wikiversity
Jump to navigation Jump to search
Important! These pages are somehow outdated and it is recommended to consult the newer version at Computer graphics -- 2008-2009 -- info.uvt.ro (by Marc Frâncu).

Quick links: front; laboratories agenda, 1, 2, 3, 4, 5, 6, 7, 8, evaluation, tools, repository.


Texture sphere mapping[edit]

Please consult Computer graphics -- 2007-2008 -- info.uvt.ro/Laboratory 5#Mapping a texture onto a sphere.

Texture blending and transparency[edit]

Discussion 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]

Example[edit]

The 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[edit]

Discussions 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[edit]

Example[edit]

The 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[edit]

This 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);