Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CS 468 OpenGL Jon Moon Spring 2004 Computer Science Cornell University Who am I? Jon Moon University of Minnesota ’03 First year PhD [email protected] 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.unibielefeld.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/uiswi ng/mini/index.html