CS 468 OpenGL Jon Moon Spring 2004 Computer Science Cornell University
Who am I? Jon Moon University of Minnesota ’03 First year PhD Office: 4143 Upson
The Plan What is OpenGL? OpenGL basic interactions OpenGL with Java: JOGL Sample code: General framework 3D Transformations Lighting
What is OpenGL? It’s a graphics API: Software layer that sits between the programmer and the CPU, GPU It’s window system and platform independent It’s fast and easy to use
What is OpenGL? It’s a renderer: Primitives are points, lines, polygons… It’s a State Machine: The output of the renderer depends on the state, which includes: Current color, normal, etc. Shading, lighting Viewing All sorts of other stuff
Viewing in OpenGL OpenGL maintains two viewing matrices: Model view matrix: for object positions Projection matrix: for camera properties Projection can be perspective or orthographic Camera is always at the origin, looking toward -z
OpenGL with Java: enter JOGL JOGL is a java binding for the OpenGL API. JOGL is not very object oriented: Make a single GL object, which then has methods, fields Basically a wrapped c header file gl.h Simple to port C code to java this way
Enough talk, where’s the code? import... import net.java.games.jogl.*; public class OpenGLDemo01 extends JFrame implements GLEventListener { public OpenGLDemo01() {...} public static void main(String[] args) {new OpenGLDemo01();} public void init(...) {} public void reshape(...) {...} public void display(...) {...} public void displayChanged(...) {} }
Demo 1, high level Constructor handles window: canvas, JPanel Main simply creates an instance Init sets some start state stuff Reshape sets the modelview and projection matrices and viewport Display specifies geometry and transformation
Demo 1: constructor public OpenGLDemo01() { super("OpenGL Demo 01"); setLocation(100, 100); setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); canvas = GLDrawableFactory.getFactory(). createGLCanvas(new GLCapabilities()); canvas.addGLEventListener(this); JPanel glPanel = new JPanel(new BorderLayout()); glPanel.add(canvas, BorderLayout.CENTER); glPanel.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); getContentPane().add(glPanel); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); show(); }
Demo1: reshape public void reshape(GLDrawable gLDrawable, int x, int y, int width, int height) { final GL gl = gLDrawable.getGL(); final GLU glu = gLDrawable.getGLU(); gl.glViewport(0, 0, width, height); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); glu.gluOrtho2D(0, VIEWPORT_WIDTH, 0, VIEWPORT_HEIGHT); gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); }
Demo1: display public void display(GLDrawable gLDrawable) { final GL gl = gLDrawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT);// gl.glBegin(gl.GL_TRIANGLES); gl.glColor3d(1.0, 0.0, 0.0); gl.glVertex2i(250, 450); gl.glColor3d(0.0, 1.0, 0.0); gl.glVertex2i(50, 50); gl.glColor3d(0.0, 0.0, 1.0); gl.glVertex2i(450, 50); gl.glEnd(); }
That wasn’t so bad, was it? But that was just 2D – drawing a triangle isn’t exactly amazing Suppose we wanted to draw a perspective (3D) cube: What would have to change? Camera type Geometry Hidden Surface removal!
Demo2: Init public void init(GLDrawable gLDrawable) { final GL gl = gLDrawable.getGL(); gl.glEnable(gl.GL_DEPTH_TEST); }
Demo2: reshape changes... gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(45.0f, (float) width / (float) height, 0.2f, 100.0f); glu.gluLookAt(3.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);...
Demo2: display changes... gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glBegin(gl.GL_QUADS); // Front Face gl.glColor3d(0.0, 0.0, 1.0); gl.glVertex3f(-1.0f, -1.0f, 1.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f); gl.glVertex3f(1.0f, 1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f);...
Demo2: That’s it! Booya -- perspective 3D cube. glu.gluPerspective and glu.gluLookAt HSR accomplished by enabling z- buffer, gl.glEnable(gl.GL_DEPTH_TEST) and clearing it for each display Use gl.glBegin(GL_QUADS): list vertices in groups of 4, changing color/normals if desired
Demo3: Using the Model View Matrix Even 3D perspective cubes get boring… what if we wanted it to spin? Recall that the Model View matrix is part of the state of OpenGL: Changing it in one display call will persist until it is changed again. Let’s call the display method regularly, and each time tweak model view matrix
Demo3: Using the Model View Matrix In display, we make this call: gl.glRotatef(0.5f, 1.0f, 1.6f, 0.7f); “rotate.5 degrees around the vector {1,1.6,.7}” More accurately, “calculate the matrix for that rotation, and multiply the Model View matrix by it” Other nifty matrix changing calls: gl.glTranslatef(x,y,z) gl.glScalef(x,y,z)
Matrix stacks OpenGL maintains multiple matrix stacks gl.glPushMatrix pushes a copy of the current matrix onto the stack gl.glPopMatrix discards the top of the stack What is this useful for?
Demo4: Hierarchical transforms Goal: box with two small boxes on top Non-hierarchical method: Draw big base box Translate, rotate, scale into desired position of 2 nd box, draw it Translate, rotate, scale over to desired 3 rd box position, draw it? (or…) But 3 rd should be relative to 1 st
Demo4: Hierarchical transforms Hierarchical method: Draw big base box Push current matrix onto stack Transform to draw 2 nd box Pop matrix from stack Back in coordinates of base box! Push matrix again Transform to draw 3 rd box Pop matrix
Demo4: Do it in OpenGL gl.glPushMatrix(); gl.glScalef(1,.3f,1); drawCube(gl); //just draws standard cube gl.glPushMatrix(); gl.glTranslatef(.5f,2f,0); gl.glScalef(0.3f,1f,0.3f); gl.glRotatef(15,0,1,0); drawCube(gl); gl.glPopMatrix(); gl.glPushMatrix(); gl.glTranslatef(-.5f,2f,0); gl.glScalef(0.2f,1f,0.2f); drawCube(gl); gl.glPopMatrix();
Demo5: The last one, I promise What about lighting? You can specify lights as part of the OpenGL state – position, color, emission, type, and more First define a light: float lightColor[] = {1.0f, 1.0f, 1.0f}; gl.glLightfv(gl.GL_LIGHT0, gl.GL_COLOR, lightColor ); (similar for position, etc) Then, enable it: glEnable(gl.GL_LIGHTING); glEnable(gl.GL_LIGHT0);
Demo5: Materials too! Can also define a material as part of the state: float materialColor[] = {1.0f, 1.0f, 0.0f}; gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE, materialColor); Don’t worry much about lighting and materials in OpenGL; we can do much cooler stuff with Cg.
Other resources: JOGL home: GL, GLU function descriptions: bielefeld.de/doc/OpenGL/hp/Reference.html bielefeld.de/doc/OpenGL/hp/Reference.html Java API spec: Swing guides: ng/mini/index.html ng/mini/index.html