260 likes | 547 Views
CS 468 OpenGL. Jon Moon Spring 2004 Computer Science Cornell University. Who am I?. Jon Moon University of Minnesota ’03 First year PhD jmoon@cs.cornell.edu Office: 4143 Upson. The Plan. What is OpenGL? OpenGL basic interactions OpenGL with Java: JOGL Sample code: General framework
E N D
CS 468OpenGL Jon Moon Spring 2004 Computer Science Cornell University
Who am I? • Jon Moon • University of Minnesota ’03 • First year PhD • jmoon@cs.cornell.edu • 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 1800+ methods, 2400+ 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 2nd box, draw it • Translate, rotate, scale over to desired 3rd box position, draw it? (or…) • But 3rd should be relative to 1st
Demo4: Hierarchical transforms • Hierarchical method: • Draw big base box • Push current matrix onto stack • Transform to draw 2nd box • Pop matrix from stack • Back in coordinates of base box! • Push matrix again • Transform to draw 3rd 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(); 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: https://jogl.dev.java.net/ • GL, GLU function descriptions: http://tc1.chemie.uni-bielefeld.de/doc/OpenGL/hp/Reference.html • Java API spec: http://java.sun.com/j2se/1.4.2/docs/api/ • Swing guides: http://java.sun.com/docs/books/tutorial/uiswing/mini/index.html