Jogl Polygon Rendering/Shading Problem

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Jogl Polygon Rendering/Shading Problem

lalarama
Hello to everybody who reads this.

I'm currently working on a project containing geographic data of houses, streets and other stuff.
To visualize the data i wrote a Jogl 2.0 player. Everything works fine so far. The only thing i don't get is why all my polygons which the houses are drawn with look the same.
First two picture to help understanding the problem:

Scenario before loading other objects
Scenario before loading other objects

Scenario after loading other objects


As you can see, i added the GLUT Teapot to show that lighting works on glu objects like the spheres of the trees,  glut objects and even the normal gl ones. But as you can see, the sides and roofs don't have any shading and all look the same.
Basicly the setup is very much from the examples, with only a few changes.

I added the code of the classes which actually draw the the stuff below.
The first one is the whole window class which does the moin jogl setup and drawing.
The second one is a abstract class which from which several drawstyle classes are extended.
The third one is such a extended class and the one used for the second picture above.

To make it a bit easier: The polygons are drawn in the display loop of the frame by the DrawManager which does it like this:

 else if (object instanceof Polygon) {
        Polygon polygon = (Polygon)object;
        if (!polygon.isClockwise())
                gl.glFrontFace (GL2.GL_CCW); // counter clockwise
        else
                gl.glFrontFace(GL2.GL_CW); // clockwise
        gl.glShadeModel(GL2.GL_SMOOTH);
                                               
        gl.glBegin(GL2.GL_POLYGON);
        setMaterial(gl, polygon.getColor3f());
        //gl.glColor3f(polygon.getColor3f().x, polygon.getColor3f().y, polygon.getColor3f().z);
        for (int i = 0; i < coordinates.size(); i++) {
                gl.glVertex3f((float)coordinates.get(i).x, (float)coordinates.get(i).y, (float)coordinates.get(i).z);
        }
        gl.glEnd();
}

their material properties are set by:

public void setMaterial(GL2 gl, Color3f color, float alpha) {
        mat[0] = color.x;
        mat[1] = color.y;
        mat[2] = color.z;
        mat[3] = alpha;
               
        float mat_diffuse[] = {0.1f, 0.1f, 0.1f, 0.0f};
        float mat_specular[] = {0.7f, 0.7f, 0.7f, 0.7f};
        float mat_shininess = 50f;
        float mat_emission[] = {0.1f, 0.1f, 0.1f, 0.1f};
       
        gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, mat,0 );
        gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, mat_diffuse,0 );
        gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, mat_specular,0 );
        gl.glMaterialf( GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, mat_shininess );
        gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, mat_emission,0 );
   }

For the sides of the houses the setMaterial is called with 0.5 0.5 0.5 1.0 (grey and 1.0 for the alpha).

My guess was that ..

if (!polygon.isClockwise())
     gl.glFrontFace (GL2.GL_CCW); // counter clockwise
else
    gl.glFrontFace(GL2.GL_CW); // clockwise
gl.glShadeModel(GL2.GL_SMOOTH);

..could be the problem but removing it resulted in no changes at all.

I case you are wondering about the change of color of the teapot above:
It is drawn without material properties and therefore is given those of the last DrawManager object which in this case was a roof. That makes me even wonder more what is wrong with the polygons as the roofs have therefore the same material as the teapot in the second picture....

I am completly new to Jogl and therefore have no clue at all why the polygons are not shaded. Perhaps somebody has an idea where this could come from.

Thanks a lot to everyone who has some advice.

Lalarama

P.S. i hope my English was not too bad

Sources below this line :)--------------------------------------------

JoglWindow.java
AbstractJoglDrawableMethods.java
JoglDrawableMethodsNormal.java


Code of the Main JOGL Frame--------------------------------------------------------------------------------------------------

package de.wb3player.render.jogl;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.FloatBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.vecmath.Vector3d;

import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.GLBuffers;
import com.jogamp.opengl.util.gl2.GLUT;

import de.wb3player.controller.WB3Controller;
import de.wb3player.fileaccess.output.drawstyle.DrawableMethods;
import de.wb3player.fileaccess.output.drawstyle.jogl.AbstractJoglDrawableMethods;
import de.wb3player.model.ModelManager;
import de.wb3player.model.exception.DrawableMethodsException;
import de.wb3player.render.menu.JoglMenuBar;
import de.wb3player.render.menu.ObjectTreeFrame;

public class JoglWindow extends JFrame implements GLEventListener {
               
        /**
         *
         */
        private static final long serialVersionUID = 4207632556046308249L;
       
        private static final int FPS = 60;   // Animator's target frames per second
       
        private int width;
        private int height;
       
        private JoglMenuBar menuBar;
       
        long lastTime = 0;
        int delta = 0;
       
        private GL2 gl;
        private GLU glu;
        private GLUT glut;
       
        private final FloatBuffer mouseZ = GLBuffers.newDirectFloatBuffer(1);
         
        private Vector3d pickPosition = null;
       
       
       
        public JoglWindow(int posX, int posY, int width, int height) {
                super();
                               
                this.width = width;
                this.height = height;
               
                this.setTitle("WB3 Player");
       
                // Get the default OpenGL profile that best reflect your running platform.
                GLProfile glProfile = GLProfile.getDefault();
                // Specifies a set of OpenGL capabilities, based on your profile.
                GLCapabilities glCapabilities = new GLCapabilities(glProfile);
                glCapabilities.setDoubleBuffered(true);
                glCapabilities.setNumSamples(4);
                glCapabilities.setSampleBuffers(true);
               
                // Allocate a GLDrawable, based on your OpenGL capabilities.
                final GLCanvas canvas = new GLCanvas(glCapabilities);
        final FPSAnimator fpsAnimator = new FPSAnimator(canvas, FPS);
       
        this.addMouseListener(WB3Controller.getInstance());
        this.addMouseMotionListener(WB3Controller.getInstance());
                this.addMouseWheelListener(WB3Controller.getInstance());    
                this.addKeyListener(WB3Controller.getInstance());
       
        canvas.addGLEventListener(this);
       
        canvas.addMouseListener(WB3Controller.getInstance());
        canvas.addMouseMotionListener(WB3Controller.getInstance());
        canvas.addMouseWheelListener(WB3Controller.getInstance());    
        canvas.addKeyListener(WB3Controller.getInstance());
               
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       
        //make menus appear above GLCanvas
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
               
        //add the menu bar
        this.menuBar = new JoglMenuBar(this);
        this.setJMenuBar(this.menuBar);
       
        this.add(canvas);
        this.setBounds(posX, posY, width, height);
       
        this.addWindowListener(new WindowAdapter() {
 
            @Override
            public void windowClosing(final WindowEvent e) {
 
                new Thread(new Runnable() {
                    public void run() {
 
                    fpsAnimator.stop();
                        System.exit(0);
 
                    }
 
                }).start();
            }
        });
 
//        this.setLocationRelativeTo(null);
        this.setVisible(true);
        fpsAnimator.start();
        }
       
       
        @Override
        public void display(GLAutoDrawable drawable) {
               
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                gl.glLoadIdentity();
               
        try {
                        ModelManager.getInstance().draw();
                } catch (DrawableMethodsException e) {
                        e.printStackTrace();
                }
        gl.glPushMatrix();
        gl.glTranslated(0.0, 0.0, 20.0);
        gl.glRotated(90.0, 1.0, 0.0, 0.0);
       
        glut.glutSolidTeapot(4.0);
        gl.glPopMatrix();
       
        setCamera(gl, glu);
        ModelManager.getInstance().getAdvancedCameraDirector().update();
       
        pick(WB3Controller.getInstance().getCurrentX(), WB3Controller.getInstance().getCurrentY());
        }
       
        @Override
        public void dispose(GLAutoDrawable drawable) {
                // TODO Auto-generated method stub
                       
        }
       
        @Override
        public void init(GLAutoDrawable drawable) {
                gl = drawable.getGL().getGL2();
                glu = new GLU();
                glut = new GLUT();
               
                // Enable smooth shading, which blends colors nicely, and smoothes out lighting.
                gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
                // Set background color in RGBA. Alpha: 0 (transparent) 1 (opaque)
                gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);  
                // Setup the depth buffer and enable the depth testing
                gl.glClearDepth(1.0f);         // clear z-buffer to the farthest
                gl.glEnable(GL.GL_DEPTH_TEST); // enables depth testing
                gl.glDepthFunc(GL.GL_LEQUAL);  // the type of depth test to do
                // Do the best perspective correction
                gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
               
// gl.glEnable(GL.GL_LINE_SMOOTH); //enables line smoothing
// gl.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_DONT_CARE);
               
                for (DrawableMethods drawableMethods : ModelManager.getInstance().getDrawableMethods()) {
                        if (drawableMethods instanceof AbstractJoglDrawableMethods) {
                                ((AbstractJoglDrawableMethods)drawableMethods).setGL(gl, glu);
                        }
                }
               
                this.setLight(gl);
               
        }
       
        @Override
        public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, int height) {
               
                this.width = width;
                this.height = height;
               
                if (height <= 0)
            height = 1;
 
                setCamera(gl, glu);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
        }
       
        private void setCamera(GL2 gl, GLU glu) {
        // Change to projection matrix.
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();

        // Perspective.
        gl.glViewport(0, 0, width, height);                 // Reset The Current Viewport And Perspective Transformation
        glu.gluPerspective(45.0f, (float)width/height, 0.1f, 100000.0f);  // Calculate The Aspect Ratio Of The Window
               
        glu.gluLookAt( ModelManager.getInstance().getCamera().getEyePosX(),
                        ModelManager.getInstance().getCamera().getEyePosY(),
                        ModelManager.getInstance().getCamera().getEyePosZ(),
                        ModelManager.getInstance().getCamera().getLookAtX(),
                        ModelManager.getInstance().getCamera().getLookAtY(),
                        ModelManager.getInstance().getCamera().getLookAtZ(),
                        ModelManager.getInstance().getCamera().getUpVectorX(),
                        ModelManager.getInstance().getCamera().getUpVectorY(),
                        ModelManager.getInstance().getCamera().getUpVectorZ());
               
        // Change back to model view matrix.
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
       
        private void setLight(GL2 gl) {
                // Set up lighting
                float[] lightAmbient = {0.9f, 0.9f, 0.9f, 0.9f};
                float[] lightDiffuse = {0.9f, 0.9f, 0.9f, 0.9f};
                float[] lightSpecular = {0.7f, 0.7f, 0.7f, 1.0f};
                float[] lightPosition = {100.0f, -100.0f, 200.0f, 1.0f};
               
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, lightAmbient, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, lightDiffuse, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, lightSpecular, 0);
        gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPosition, 0);
 
        gl.glEnable(GL2.GL_LIGHTING);
        gl.glEnable(GL2.GL_LIGHT0);
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glEnable(GL2.GL_SMOOTH);
           
            //gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);    
        }
                       
        public void showMessageDialog(String text) {
                JOptionPane.showMessageDialog(this,text);
        }
       
        public void showObjectTree() {
                ObjectTreeFrame objectTreeFrame = new ObjectTreeFrame();
                objectTreeFrame.setVisible(true);
        }
               
        private void pick(int mouseX, int mouseY) {
                 
        final int[] vp = new int[4];
        final double[] mv = new double[16];
        final double[] p = new double[16];
        final double[] result = new double[3];
 
        gl.glGetIntegerv(GL.GL_VIEWPORT, vp, 0);
        gl.glGetDoublev(GL2.GL_MODELVIEW_MATRIX, mv, 0);
        gl.glGetDoublev(GL2.GL_PROJECTION_MATRIX, p, 0);
 
        gl.glReadPixels(mouseX, mouseY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, mouseZ);
 
        glu.gluUnProject(mouseX, mouseY, mouseZ.get(0), mv, 0, p, 0, vp, 0, result, 0);
 
        Vector3d resultPosition = new Vector3d(result[0],result[1],result[2]);
         
        this.pickPosition = new Vector3d(resultPosition.x,
                                                        resultPosition.y,
                                                        resultPosition.z);
    }
       
        public Vector3d pick() {
                return this.pickPosition;
        }
}

Code of the Abstract Drawstyle class which add the objects use to draw-------------------------------------------------------------------------------------------------

package de.wb3player.fileaccess.output.drawstyle.jogl;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.vecmath.Color3f;

import de.wb3player.fileaccess.output.drawstyle.DrawableMethods;
import de.wb3player.logger.LoggerFactory;
import de.wb3player.logger.LoggerInterface;
import de.wb3player.model.exception.DrawableMethodsException;

public abstract class AbstractJoglDrawableMethods implements DrawableMethods {


        protected static LoggerInterface logger = LoggerFactory.getLoggerInstance(AbstractJoglDrawableMethods.class);
       
        protected float mat[] = new float[4];
       
        protected GL2 gl;
        protected GLU glu;

        protected String name = "AbstractJoglDrawableMethods";
        protected String description = "AbstractJoglDrawableMethods: methods for drawing WB3 objects in JOGL";
       
       
        public AbstractJoglDrawableMethods() {
                logger.debug("Constructor called");
               
        }
       
        public void setGL(GL2 gl, GLU glu) {
                this.gl = gl;
                this.glu = glu;
        }
       
               
        @Override
        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        @Override
        public String getDescription() {
                return description;
        }

        public void setDescription(String description) {
                this.description = description;
        }

        @Override
        public abstract void draw(Object object) throws DrawableMethodsException;
       
        public void setMaterial(GL2 gl, Color3f color, float alpha) {
                mat[0] = color.x;
                mat[1] = color.y;
                mat[2] = color.z;
                mat[3] = alpha;
               
                float mat_diffuse[] = {0.1f, 0.1f, 0.1f, 0.0f};
        float mat_specular[] = {0.7f, 0.7f, 0.7f, 0.7f};
        float mat_shininess = 50f;
        float mat_emission[] = {0.1f, 0.1f, 0.1f, 0.1f};
               
       
                gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, mat,0 );
                gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, mat_diffuse,0 );
                gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, mat_specular,0 );
                gl.glMaterialf( GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, mat_shininess );
                gl.glMaterialfv( GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, mat_emission,0 );
               
    }
       
        public void setMaterial(GL2 gl, Color3f color) {
                setMaterial(gl, color, 1.0f);
        }

}

Code of one example drawstyle class extending the abstract drawstyle class  -------------------------------------------------------------------------------------------------

package de.wb3player.fileaccess.output.drawstyle.jogl;

import java.util.ArrayList;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.vecmath.Vector3d;

import de.wb3player.fileaccess.output.drawstyle.DrawableMethods;
import de.wb3player.fileaccess.output.objects.Drawable;
import de.wb3player.fileaccess.output.objects.drawable.Line;
import de.wb3player.fileaccess.output.objects.drawable.Point;
import de.wb3player.fileaccess.output.objects.drawable.Polygon;
import de.wb3player.fileaccess.output.objects.drawable.sql.BoundingBox;
import de.wb3player.fileaccess.output.objects.drawable.sql.Lamp3D;
import de.wb3player.fileaccess.output.objects.drawable.sql.Pipe3D;
import de.wb3player.fileaccess.output.objects.drawable.sql.Plant3D;
import de.wb3player.model.exception.DrawableMethodsException;
import de.wb3player.toolbox.Toolbox;

public class JoglDrawableMethodsNormal extends AbstractJoglDrawableMethods implements DrawableMethods {
       
        protected String nameSpecific = "Normal";
        protected String descriptionSpecific = "JoglDrawableMethodsNormal: methods for drawing WB3 objects in JOGL";
       
        public JoglDrawableMethodsNormal() {
                super();
                this.name = nameSpecific;
                this.description = descriptionSpecific;
        }

        @Override
        public void draw(Object object) throws DrawableMethodsException{
                if (this.gl == null && this.glu == null) {
                        throw new DrawableMethodsException("JoglDrawableMethodsExtended: GL and/or GLU not initialized");
                }
                if (object instanceof Drawable) {
                        Drawable drawable = (Drawable)object;
                        ArrayList<Vector3d> coordinates = (ArrayList<Vector3d>)drawable.getCoordinates();
                        if (object instanceof Point) {
                                Point point = (Point)object;
                                gl.glPointSize(point.getPointSize());
                                gl.glBegin(GL.GL_POINTS);
                                setMaterial(gl, point.getColor3f());
                                //gl.glColor3f(point.getColor3f().x, point.getColor3f().y, point.getColor3f().z);
                                gl.glVertex3f((float)coordinates.get(0).x, (float)coordinates.get(0).y, (float)coordinates.get(0).z);
                                gl.glEnd();
                               
                        } else if (object instanceof Plant3D) {
                                Plant3D plant = (Plant3D)object;
                                double trunkHeight = plant.getHeight() - plant.getCrownDiameter();
                                //trunk
                                gl.glPushMatrix();
                                gl.glTranslated(coordinates.get(0).x, coordinates.get(0).y, coordinates.get(0).z);
                                setMaterial(gl, plant.getTrunkColor());
                                //gl.glColor3f(plant.getTrunkColor().x, plant.getTrunkColor().y, plant.getTrunkColor().z);
                                GLUquadric gluTrunkQuadric = glu.gluNewQuadric();
                                glu.gluQuadricDrawStyle(gluTrunkQuadric, GLU.GLU_FILL);
                                glu.gluQuadricNormals(gluTrunkQuadric, GLU.GLU_SMOOTH);
                                glu.gluCylinder(gluTrunkQuadric, plant.getTrunkDiameter(), plant.getTrunkDiameter(), trunkHeight, 15, 5);
                                glu.gluDeleteQuadric(gluTrunkQuadric);
                                gl.glPopMatrix();
                                //crown
                                gl.glPushMatrix();
                                gl.glTranslated(coordinates.get(0).x, coordinates.get(0).y, (coordinates.get(0).z + (plant.getHeight()-plant.getCrownDiameter()/2)));
                                setMaterial(gl, plant.getColor3f());
                                //gl.glColor3f(plant.getColor3f().x, plant.getColor3f().y, plant.getColor3f().z);
                                GLUquadric gluCrownQuadric = glu.gluNewQuadric();
                                glu.gluQuadricDrawStyle(gluCrownQuadric, GLU.GLU_FILL);
                                glu.gluQuadricNormals(gluCrownQuadric, GLU.GLU_SMOOTH);
                                glu.gluSphere(gluCrownQuadric, (plant.getCrownDiameter()/2), 16, 16);
                                glu.gluDeleteQuadric(gluCrownQuadric);
                                gl.glPopMatrix();
                               
                        }  else if (object instanceof Lamp3D) {
                                Lamp3D lamp3D = (Lamp3D)object;
                                gl.glPushMatrix();
                                gl.glTranslated(coordinates.get(0).x, coordinates.get(0).y, coordinates.get(0).z);
                                setMaterial(gl, lamp3D.getColor3f());
                                //gl.glColor3f(plant.getTrunkColor().x, plant.getTrunkColor().y, plant.getTrunkColor().z);
                                GLUquadric gluTrunkQuadric = glu.gluNewQuadric();
                                glu.gluQuadricDrawStyle(gluTrunkQuadric, GLU.GLU_FILL);
                                glu.gluQuadricNormals(gluTrunkQuadric, GLU.GLU_SMOOTH);
                                glu.gluCylinder(gluTrunkQuadric, 0.2, 0.2, 3.0, 15, 5);
                                glu.gluDeleteQuadric(gluTrunkQuadric);
                                gl.glPopMatrix();
                                                                       
                               
                        } else if (object instanceof Line) {
                                Line line = (Line)object;
                                for (int i = 0; i < coordinates.size()-1; i++) {
                                        setMaterial(gl, line.getColor3f());
                                        gl.glLineWidth(line.getLineWidth());
                                        gl.glBegin(GL2.GL_LINES);
                                        gl.glVertex3f((float)coordinates.get(i).x, (float)coordinates.get(i).y, (float)coordinates.get(i).z);
                                        gl.glVertex3f((float)coordinates.get(i+1).x, (float)coordinates.get(i+1).y, (float)coordinates.get(i+1).z);
                                        gl.glEnd();
                                }
                       
                        } else if (object instanceof Polygon) {
                                Polygon polygon = (Polygon)object;
                                if (!polygon.isClockwise())
                                        gl.glFrontFace (GL2.GL_CCW); // counter clockwise
                                else
                                        gl.glFrontFace(GL2.GL_CW); // clockwise
                                gl.glShadeModel(GL2.GL_SMOOTH);
                                               
                                gl.glBegin(GL2.GL_POLYGON);
                                setMaterial(gl, polygon.getColor3f());
                                //gl.glColor3f(polygon.getColor3f().x, polygon.getColor3f().y, polygon.getColor3f().z);
                                for (int i = 0; i < coordinates.size(); i++) {
                                        gl.glVertex3f((float)coordinates.get(i).x, (float)coordinates.get(i).y, (float)coordinates.get(i).z);
                                }
                                gl.glEnd();
                               
                        } else if (object instanceof BoundingBox) {
                                BoundingBox boundingBox = (BoundingBox)object;
                                if (coordinates.size() == 2) {
                                        setMaterial(gl, boundingBox.getColor3f(),0.2f);
                                        //gl.glColor3f(boundingBox.getColor3f().x, boundingBox.getColor3f().y, boundingBox.getColor3f().z);
                                        gl.glBegin(GL2.GL_POLYGON);
                                        gl.glVertex3f((float)coordinates.get(0).x, (float)coordinates.get(0).y, (float)coordinates.get(0).z);
                                        gl.glVertex3f((float)coordinates.get(0).x, (float)coordinates.get(1).y, (float)coordinates.get(0).z);
                                        gl.glVertex3f((float)coordinates.get(1).x, (float)coordinates.get(1).y, (float)coordinates.get(1).z);
                                        gl.glVertex3f((float)coordinates.get(1).x, (float)coordinates.get(0).y, (float)coordinates.get(1).z);
                                        gl.glEnd();
                                }
                               
                        } else if (object instanceof Pipe3D) {
                                Pipe3D pipe3D = (Pipe3D)object;
                                if (coordinates.size() >= 2) {
                                        setMaterial(gl, pipe3D.getColor3f());
                                        //draw a sphere at each coordinate
                                        for (Vector3d coordinate : coordinates) {
                                                gl.glPushMatrix();
                                                gl.glTranslated(coordinate.x, coordinate.y, coordinate.z);
                                                setMaterial(gl, pipe3D.getColor3f());
                                                //gl.glColor3f(boundingBox.getColor3f().x, boundingBox.getColor3f().y, boundingBox.getColor3f().z);
                                                GLUquadric gluEdgeQuadric = glu.gluNewQuadric();
                                                glu.gluQuadricDrawStyle(gluEdgeQuadric, GLU.GLU_FILL);
                                                glu.gluQuadricNormals(gluEdgeQuadric, GLU.GLU_SMOOTH);
                                                glu.gluSphere(gluEdgeQuadric, (pipe3D.getDiameter()/2), 16, 16);
                                                glu.gluDeleteQuadric(gluEdgeQuadric);
                                                gl.glPopMatrix();
                                        }
                                        //draw the cylinders between coordinates
                                        for (int i = 0; i < coordinates.size()-1; i++) {
                                                Vector3d fromCoordinate = coordinates.get(i);
                                                Vector3d toCoordinate = coordinates.get(i+1);
                                                double length = Toolbox.getDistanceBetweenPoints(fromCoordinate, toCoordinate);
                                                //Standard cylinder orientation
                                                Vector3d upVector = new Vector3d(0.0,0.0,1.0);
                                                //desired cylinder orientation
                                                Vector3d toVector = new Vector3d(toCoordinate.x-fromCoordinate.x, toCoordinate.y-fromCoordinate.y, toCoordinate.z-fromCoordinate.z);
                                                toVector.normalize();
                                                //cross product
                                                Vector3d crossVector = new Vector3d();
                                                crossVector.cross(upVector, toVector);
                                                double angle = 180 / Math.PI * Math.acos(upVector.dot(toVector));
                                               
                                                gl.glPushMatrix();
                                                gl.glTranslated(fromCoordinate.x, fromCoordinate.y, fromCoordinate.z);
                                                gl.glRotated(angle,crossVector.x,crossVector.y,crossVector.z);
                                                setMaterial(gl, pipe3D.getColor3f());
                                                //gl.glColor3f(plant.getTrunkColor().x, plant.getTrunkColor().y, plant.getTrunkColor().z);
                                                GLUquadric gluPipeQuadric = glu.gluNewQuadric();
                                                glu.gluQuadricOrientation(gluPipeQuadric,GLU.GLU_OUTSIDE);
                                                glu.gluQuadricDrawStyle(gluPipeQuadric, GLU.GLU_FILL);
                                                glu.gluQuadricNormals(gluPipeQuadric, GLU.GLU_SMOOTH);
                                                glu.gluCylinder(gluPipeQuadric, pipe3D.getDiameter()/2, pipe3D.getDiameter()/2, length, 15, 5);
                                                glu.gluDeleteQuadric(gluPipeQuadric);
                                                gl.glPopMatrix();
                                        }
                                }
                        }
                }
        }
       
}