/* * DisplayListModel3D.java * * Created on February 27, 2008, 11:05 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package net.java.joglutils.model.examples; import net.java.joglutils.model.*; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureCoords; import com.sun.opengl.util.texture.TextureIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.util.HashMap; import javax.imageio.ImageIO; import javax.media.opengl.GL; import javax.media.opengl.GLAutoDrawable; import net.java.joglutils.model.ResourceRetriever; import net.java.joglutils.model.geometry.Bounds; import net.java.joglutils.model.geometry.Material; import net.java.joglutils.model.geometry.Mesh; import net.java.joglutils.model.geometry.Model; import net.java.joglutils.model.geometry.Vec4; import net.java.joglutils.model.iModel3DRenderer; /** * * @author RodgersGB * * modifications made by Brian Wood and Z-Knight */ public class DisplayListRenderer implements iModel3DRenderer { private static DisplayListRenderer instance = new DisplayListRenderer(); private DisplayListCache listCache = new DisplayListCache(); private HashMap texture; private int modelBoundsList = -1; private int objectBoundsList = 1; private boolean isDebugging = true; /** Creates a new instance of DisplayListModel3D */ public DisplayListRenderer() { } public static DisplayListRenderer getInstance() { return instance; } public void debug(boolean value) { this.isDebugging = value; } public void render(Object context, Model model) { GL gl = null; if (context instanceof GL) gl = (GL) context; else if (context instanceof GLAutoDrawable) gl = ((GLAutoDrawable) context).getGL(); if (gl == null) { return; } if (model == null) { return; } int displayList = listCache.get(model); if(displayList < 0) { displayList = initialize(gl, model); if (this.isDebugging) System.out.println("Initialized the display list for model: " + model.getSource()); } // save some current state variables boolean isTextureEnabled = gl.glIsEnabled(GL.GL_TEXTURE_2D); boolean isLightingEnabled = gl.glIsEnabled(GL.GL_LIGHTING); boolean isMaterialEnabled = gl.glIsEnabled(GL.GL_COLOR_MATERIAL); // check texture if (model.isUsingTexture()) { gl.glEnable(GL.GL_TEXTURE_2D); } else { gl.glDisable(GL.GL_TEXTURE_2D); } // check wireframe if (model.isRenderingAsWireframe()) { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); } else { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); } // check lighting if (model.isUsingLighting()) { gl.glEnable(GL.GL_LIGHTING); } else { gl.glDisable(GL.GL_LIGHTING); } gl.glDisable(GL.GL_COLOR_MATERIAL); gl.glPushMatrix(); // check for unit size model if (model.isUnitizeSize()) { float scale = 1.0f/model.getBounds().getRadius(); gl.glScalef(scale, scale, scale); } if (model.isCentered()) { Vec4 center = model.getCenterPoint(); gl.glTranslatef(-center.x, -center.y, -center.z); } if (model.isRenderModel()) gl.glCallList(displayList); // Disabled lighting for drawing the boundary lines so they are all white (or whatever I chose) gl.glDisable(GL.GL_LIGHTING); if (model.isRenderModelBounds()) gl.glCallList(modelBoundsList); if (model.isRenderObjectBounds()) gl.glCallList(objectBoundsList); gl.glPopMatrix(); // Reset the flags back for lighting and texture if (isTextureEnabled) { gl.glEnable(GL.GL_TEXTURE_2D); } else { gl.glDisable(GL.GL_TEXTURE_2D); } if (isLightingEnabled) { gl.glEnable(GL.GL_LIGHTING); } else { gl.glDisable(GL.GL_LIGHTING); } if (isMaterialEnabled) { gl.glEnable(GL.GL_COLOR_MATERIAL); } else { gl.glDisable(GL.GL_COLOR_MATERIAL); } } /** * Load the model and associated materials, etc * * @param gl * @param file * @return */ private int initialize(GL gl, Model model) { if (this.isDebugging) System.out.println("Initialize Model: " + model.getSource()); int numMaterials = model.getNumberOfMaterials(); if (this.isDebugging && numMaterials > 0) { System.out.println("\n Loading " + numMaterials + " Materials:"); } String file = model.getSource(); texture = new HashMap(); for (int i=0; i 0) { System.out.println(" Load Materials: Done"); } if (this.isDebugging) System.out.println("\n Generate Lists:"); int compiledList = listCache.generateList(model, gl, 3); if (this.isDebugging) System.out.println(" Model List"); gl.glNewList(compiledList, GL.GL_COMPILE); genList(gl, model); gl.glEndList(); modelBoundsList = compiledList + 1; if (this.isDebugging) System.out.println(" Boundary List"); gl.glNewList(modelBoundsList, GL.GL_COMPILE); genModelBoundsList(gl, model); gl.glEndList(); objectBoundsList = compiledList + 2; if (this.isDebugging) System.out.println(" Object Boundary List"); gl.glNewList(objectBoundsList, GL.GL_COMPILE); genObjectBoundsList(gl, model); gl.glEndList(); if (this.isDebugging) { System.out.println(" Generate Lists: Done"); System.out.println("Load Model: Done"); } return compiledList; } /** * Load a texture given by the specified URL and assign it to the texture * id that is passed in. * * @param url * @param id */ private void loadTexture(URL url, int id) { if ( url != null ) { BufferedImage bufferedImage = null; try { bufferedImage = ImageIO.read(url); } catch (Exception e) { System.err.println(" ... FAILED loading texture with exception: "+e.getMessage()); return; } texture.put(id, TextureIO.newTexture(bufferedImage, true)); } } /** * Generate the model display list * * @param gl */ private void genList(GL gl, Model model) { TextureCoords coords; for (int i=0; i=0 && id <= model.getNumberOfMeshes()) { if (model.getMesh(id).bounds != null) { drawBounds(gl, model.getMesh(id).bounds); } } } /** * Draw the boundary of the model (the large box representing the entire * model and not the object in it) * * @param gLDrawable */ private void genModelBoundsList(GLAutoDrawable gLDrawable, Model model) { GL gl = gLDrawable.getGL(); drawBounds(gl, model.getBounds()); } /** * Draw the boundary of the model (the large box representing the entire * model and not the object in it) * * @param gl */ private void genModelBoundsList(GL gl, Model model) { drawBounds(gl, model.getBounds()); } /** * Draw the boundaries over all of the objects of the model * * @param gLDrawable */ private void genObjectBoundsList(GLAutoDrawable gLDrawable, Model model) { GL gl = gLDrawable.getGL(); genObjectBoundsList(gl, model); } /** * Draw the boundaries over all of the objects of the model * * @param gl */ private void genObjectBoundsList(GL gl, Model model) { for (int i=0; ilistCache; /** Creates a new instance of WWDisplayListCache */ private DisplayListCache() { listCache = new HashMap(); } public void clear() { listCache.clear(); } public int get(Object objID) { if (listCache.containsKey(objID)) return listCache.get(objID); else return -1; } public void remove(Object objID, GL gl, int howMany) { Integer list = listCache.get(objID); if(list != null) gl.glDeleteLists(list, howMany); listCache.remove(objID); } /** * Returns an integer identifier for an OpenGL display list based on the * object being passed in. If the object already has a display list * allocated, the existing ID is returned. */ public int generateList(Object objID, GL gl, int howMany) { Integer list = null; list = listCache.get(objID); if(list == null){ list = new Integer(gl.glGenLists(howMany)); listCache.put(objID, list); } return list; } } }