From 880653d31a8f1ff8384fdbc75b84934bceecfdb8 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 18 Nov 2000 06:43:49 +0000 Subject: Initial revision --- demos/RonsDemos/reflect.java | 424 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 demos/RonsDemos/reflect.java (limited to 'demos/RonsDemos/reflect.java') diff --git a/demos/RonsDemos/reflect.java b/demos/RonsDemos/reflect.java new file mode 100644 index 0000000..e857881 --- /dev/null +++ b/demos/RonsDemos/reflect.java @@ -0,0 +1,424 @@ +/** + * @(#) reflect.java + * @(#) author: Brian Paul (converted to Java by Ron Cemer) + */ + +/* + * Demo of a reflective, texture-mapped surface with OpenGL. + * Brian Paul August 14, 1995 This file is in the public domain. + * + * Hardware texture mapping is highly recommended! + * + * The basic steps are: + * 1. Render the reflective object (a polygon) from the normal viewpoint, + * setting the stencil planes = 1. + * 2. Render the scene from a special viewpoint: the viewpoint which + * is on the opposite side of the reflective plane. Only draw where + * stencil = 1. This draws the objects in the reflective surface. + * 3. Render the scene from the original viewpoint. This draws the + * objects in the normal fashion. Use blending when drawing + * the reflective, textured surface. + * + * This is a very crude demo. It could be much better. + */ + +/* + * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code. + * + * August 1996 - A few optimizations by Brian + */ + +/* + * April, 1997 - Added Mark Kilgard's changes. + */ + +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.*; +import java.util.*; +import java.io.*; +import java.util.*; + +import gl4java.GLContext; +import gl4java.awt.GLAnimCanvas; +import gl4java.applet.SimpleGLAnimApplet1; + +public class reflect extends SimpleGLAnimApplet1 +{ + /* Initialize the applet */ + + + public void init() + { + super.init(); + Dimension d = getSize(); + canvas = new reflectCanvas(d.width, d.height); + add("Center", canvas); + } + + + /* Local GLAnimCanvas extension class */ + + + private class reflectCanvas extends GLAnimCanvas implements MouseListener, MouseMotionListener + { + private static final float M_PI = 3.14159265359f; + private static final float DEG2RAD = (M_PI/180.0f); + private static final int MAX_OBJECTS = 2; + + private final float light_pos[] = { 0.0f, 20.0f, 0.0f, 1.0f }; + + private int textureid = 0; + + private int table_list; + private int objects_list[]; + + private float spin, xrot, yrot; + + private MatrixFuncs mtxfuncs = null; + private int prevMouseX, prevMouseY; + private boolean mouseRButtonDown = false; + + public reflectCanvas(int w, int h) + { + super(w, h); + GLContext.gljNativeDebug = false; + GLContext.gljClassDebug = false; + setAnimateFps(60.0f); + + mtxfuncs = new MatrixFuncs(); + objects_list = new int[MAX_OBJECTS]; + } + + public void preInit() + { + doubleBuffer = true; + stereoView = false; + stencilBits = 3; + } + + public void init() + { + System.out.println("init(): " + this); + reshape(getSize().width, getSize().height); + + make_table(); + make_objects(); + + int texIdBuf[] = new int[1]; + gl.glGenTextures(1, texIdBuf); + textureid = texIdBuf[0]; + + gl.glBindTexture(GL_TEXTURE_2D,textureid); + + HardCodedTexture texture = new DemoTex1(); + gl.glTexImage2D + (GL_TEXTURE_2D, + 0, + texture.getComponents(), + texture.getWidth(), + texture.getHeight(), + 0, + texture.getFormat(), + texture.getType(), + texture.getBits()); + + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + gl.glBindTexture(GL_TEXTURE_2D,0); + + spin = 0.0f; + xrot = 30.0f; + yrot = 50.0f; + + gl.glShadeModel(GL_FLAT); + + gl.glEnable(GL_LIGHT0); + gl.glEnable(GL_LIGHTING); + + gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + + gl.glEnable(GL_NORMALIZE); + + glj.gljCheckGL(); + + addMouseListener(this); + addMouseMotionListener(this); + } + + public void doCleanup() + { + System.out.println("destroy(): " + this); + removeMouseListener(this); + removeMouseMotionListener(this); + } + + public void reshape(int width, int height) + { + float aspect = (float)width / (float)height; + + gl.glViewport(0,0,width,height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glFrustum(-aspect, aspect, -1.0f, 1.0f, 4.0f, 300.0f); + gl.glMatrixMode(GL_MODELVIEW); + gl.glLoadIdentity(); + } + + public void display() + { + if (glj.gljMakeCurrent() == false) return; + + spin += 0.8f; + yrot += 1.2f; + if (yrot >= 360.0f) yrot -= 360.0f; + + float dist = 20.0f; + float eyex, eyey, eyez; + + gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + eyex = dist * (float)Math.cos(yrot*DEG2RAD) * (float)Math.cos(xrot*DEG2RAD); + eyez = dist * (float)Math.sin(yrot*DEG2RAD) * (float)Math.cos(xrot*DEG2RAD); + eyey = dist * (float)Math.sin(xrot*DEG2RAD); + + /* view from top */ + gl.glPushMatrix(); + + glu.gluLookAt(eyex,eyey,eyez,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f); + + gl.glLightfv(GL_LIGHT0, GL_POSITION, light_pos); + + /* draw table into stencil planes (non-textured for speed) */ + gl.glEnable(GL_STENCIL_TEST); + gl.glDisable(GL_DEPTH_TEST); + gl.glStencilFunc(GL_ALWAYS, 1, 0xffffffff); + gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + gl.glColorMask(false, false, false, false); + draw_table(); + gl.glColorMask(true, true, true, true); + + gl.glEnable(GL_DEPTH_TEST); + + /* render view from below (reflected viewport) */ + /* only draw where stencil==1 */ + if (eyey > 0.0f) + { + gl.glPushMatrix(); + + gl.glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */ + gl.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + gl.glScalef(1.0f, -1.0f, 1.0f); + + /* Reposition light in reflected space. */ + gl.glLightfv(GL_LIGHT0, GL_POSITION, light_pos); + + draw_objects(eyex, eyey, eyez); + gl.glPopMatrix(); + + /* Restore light's original unreflected position. */ + gl.glLightfv(GL_LIGHT0, GL_POSITION, light_pos); + } + + /* draw table into color planes (textured this time) */ + gl.glDisable(GL_STENCIL_TEST); + + gl.glEnable(GL_BLEND); + gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + gl.glBindTexture(GL_TEXTURE_2D,textureid); + gl.glEnable(GL_TEXTURE_2D); + draw_table(); + gl.glDisable(GL_TEXTURE_2D); + gl.glBindTexture(GL_TEXTURE_2D,0); + gl.glDisable(GL_BLEND); + + /* view from top */ + gl.glPushMatrix(); + + draw_objects(eyex, eyey, eyez); + + gl.glPopMatrix(); + + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + + //if (!isSuspended()) repaint(); // Animate at full speed. + } + + private void make_table() + { + float table_mat[] = { 1.0f, 1.0f, 1.0f, 0.6f }; + float gray[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + + table_list = gl.glGenLists(1); + gl.glNewList(table_list,GL_COMPILE); + + /* load table's texture */ + gl.glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,table_mat); + gl.glMaterialfv(GL_FRONT,GL_DIFFUSE,table_mat); + gl.glMaterialfv(GL_FRONT,GL_AMBIENT,gray); + + /* draw textured square for the table */ + gl.glPushMatrix(); + gl.glScalef(4.0f, 4.0f, 4.0f); + gl.glBegin(GL_POLYGON); + gl.glNormal3f(0.0f, 1.0f, 0.0f); + gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, 0.0f, 1.0f); + gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, 0.0f, 1.0f); + gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 0.0f, -1.0f); + gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 0.0f, -1.0f); + gl.glEnd(); + gl.glPopMatrix(); + + gl.glEndList(); + } + + private void make_objects() + { + int q; + + float cyan[] = { 0.0f, 1.0f, 1.0f, 1.0f }; + float green[] = { 0.2f, 1.0f, 0.2f, 1.0f }; + float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + q = glu.gluNewQuadric(); + glu.gluQuadricDrawStyle(q, GLU_FILL); + glu.gluQuadricNormals(q, GLU_SMOOTH); + + objects_list[0] = gl.glGenLists(1); + gl.glNewList(objects_list[0], GL_COMPILE); + gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan ); + gl.glMaterialfv(GL_FRONT, GL_EMISSION, black ); + glu.gluCylinder(q, 0.5f, 0.5f, 1.0f, 15, 10); + gl.glEndList(); + + objects_list[1] = gl.glGenLists(1); + gl.glNewList(objects_list[1], GL_COMPILE); + gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gl.glMaterialfv(GL_FRONT, GL_EMISSION, black); + glu.gluCylinder(q, 1.5, 0.0f, 2.5f, 15, 10); + gl.glEndList(); + } + + + private void draw_objects(float eyex, float eyey, float eyez) + { + gl.glPushMatrix(); + gl.glTranslatef(1.0f, 1.5f, 0.0f); + gl.glRotatef(spin, 1.0f, 0.5f, 0.0f); + gl.glRotatef(0.5f*spin, 0.0f, 0.5f, 1.0f); + gl.glCallList(objects_list[0]); + gl.glPopMatrix(); + + gl.glPushMatrix(); + gl.glTranslatef(-1.0f, 0.85f+3.0f*(float)Math.abs((float)Math.cos(0.01f*spin)),0.0f); + gl.glRotatef(0.5f*spin, 0.0f, 0.5f, 1.0f); + gl.glRotatef(spin, 1.0f, 0.5f, 0.0f); + gl.glScalef(0.5f, 0.5f, 0.5f); + gl.glCallList(objects_list[1]); + gl.glPopMatrix(); + } + + private void draw_table() + { + gl.glCallList(table_list); + } + + float[] MatrixTransform(float m[], float vx, float vy, float vz, float vw) + { + float v[] = new float[4]; + float nx, ny, nz, nw, ninvw; + + nx = ((vx*m[0])+(vy*m[4])+(vz*m[ 8])+(vw*m[12])); + ny = ((vx*m[1])+(vy*m[5])+(vz*m[ 9])+(vw*m[13])); + nz = ((vx*m[2])+(vy*m[6])+(vz*m[10])+(vw*m[14])); + nw = ((vx*m[3])+(vy*m[7])+(vz*m[11])+(vw*m[15])); + if ( (nw != 0.0f) && (nw != 1.0f) ) + { + ninvw = 1.0f/nw; + nx *= ninvw; + ny *= ninvw; + nz *= ninvw; + } + v[0] = nx; + v[1] = ny; + v[2] = nz; + v[3] = 1.0f; + return(v); + } + + // Methods required for the implementation of MouseListener + public void mouseEntered( MouseEvent evt ) + { + } + + public void mouseExited( MouseEvent evt ) + { + } + + public void mousePressed( MouseEvent evt ) + { + prevMouseX = evt.getX(); + prevMouseY = evt.getY(); + if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0) + { + mouseRButtonDown = true; + evt.consume(); + } + } + + public void mouseReleased( MouseEvent evt ) + { + if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0) + { + mouseRButtonDown = false; + evt.consume(); + } + } + + public void mouseClicked( MouseEvent evt ) + { + } + + // Methods required for the implementation of MouseMotionListener + public void mouseDragged( MouseEvent evt ) + { + int x = evt.getX(); + int y = evt.getY(); + float thetaX = (float)(x-prevMouseX)*(360.0f/(float)getSize().width); + float thetaY = (float)(prevMouseY-y)*(360.0f/(float)getSize().height); + float mtxbuf[] = new float[16]; + float mtxbuf2[] = new float[16]; + + prevMouseX = x; + prevMouseY = y; + if ( (thetaX != 0.0f) || (thetaY != 0.0f) ) + { +// This is a special hack for this applet only, due to +// the fact that we are not using a rotation matrix!!! + yrot += thetaX; + while (yrot < 0.0f) yrot += 360.0f; + while (yrot >= 360.0f) yrot -= 360.0f; + + xrot -= thetaY; + if (xrot > 90.0f) + xrot = 90.0f; + else if (xrot < -90.0f) + xrot = -90.0f; + } + evt.consume(); + } + + public void mouseMoved( MouseEvent evt ) + { + } + } +} -- cgit v1.2.3