diff options
author | phil <[email protected]> | 2016-10-26 18:01:03 +1300 |
---|---|---|
committer | phil <[email protected]> | 2016-10-26 18:01:03 +1300 |
commit | fe4c2af5303d6d25a275e197c701e854dc3dfba7 (patch) | |
tree | e7d50bfb797f9972638ec2d7bc51ffbe54ccaa73 | |
parent | 44dd75f8741d5c79592b7f2e15091151fcce9c5b (diff) |
Added a stencil outline example
This is primarily to test
Bug 1325 - JoglPipeline.resetRenderingAttributes does not call
gl.glDisable(GL.GL_STENCIL_TEST);
-rw-r--r-- | src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java | 249 | ||||
-rw-r--r-- | src/classes/org/jdesktop/j3d/examples/stencil/StencilOutline.java | 527 |
2 files changed, 776 insertions, 0 deletions
diff --git a/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java b/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java new file mode 100644 index 0000000..f06f9e9 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java @@ -0,0 +1,249 @@ +package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.vecmath.Color3f;
+
+/**
+ * Note all of these are no lighting shaders, so materials are always ignored
+ * @author phil
+ *
+ */
+public class SimpleShaderAppearance extends ShaderAppearance
+{
+ private static GLSLShaderProgram flatShaderProgram;
+ private static GLSLShaderProgram textureShaderProgram;
+ private static GLSLShaderProgram colorLineShaderProgram;
+
+ public static String alphaTestUniforms = "uniform int alphaTestEnabled;\n" + //
+ "uniform int alphaTestFunction;\n" + //
+ "uniform float alphaTestValue;\n";
+
+ public static String alphaTestMethod = "if(alphaTestEnabled != 0)\n" + //
+ "{ \n" + //
+ " if(alphaTestFunction==516)//>\n" + //
+ " if(baseMap.a<=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==518)//>=\n" + //
+ " if(baseMap.a<alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==514)//==\n" + //
+ " if(baseMap.a!=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==517)//!=\n" + //
+ " if(baseMap.a==alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==513)//<\n" + //
+ " if(baseMap.a>=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==515)//<=\n" + //
+ " if(baseMap.a>alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==512)//never \n" + //
+ " discard; \n" + //
+ "}\n";
+
+ /**
+ * Polygons no texture, no single color, must have color vertex attribute
+ */
+ public SimpleShaderAppearance()
+ {
+ this(null, false);
+ }
+
+ /**
+ * Lines with a single color no texture, ignores vertex attribute of color
+ * @param color
+ */
+ public SimpleShaderAppearance(Color3f color)
+ {
+ this(color, false);
+ }
+
+ /**
+ * Polygons if hasTexture is true a texture otherwise vertex attribute colors for face color
+ */
+ public SimpleShaderAppearance(boolean hasTexture)
+ {
+ this(null, hasTexture);
+ }
+
+ /** if color is not null then a line appearance
+ * otherwise simple poly appearance
+ * @param color
+ */
+ private SimpleShaderAppearance(Color3f color, boolean hasTexture)
+ {
+ if (hasTexture)
+ {
+ RenderingAttributes ra = new RenderingAttributes();
+ setRenderingAttributes(ra);
+
+ if (textureShaderProgram == null)
+ {
+ textureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance textureShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec2 glMultiTexCoord0;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec2 glTexCoord0;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "glTexCoord0 = glMultiTexCoord0.st;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += alphaTestUniforms;
+ fragmentProgram += "varying vec2 glTexCoord0;\n";
+ fragmentProgram += "uniform sampler2D BaseMap;\n";
+ fragmentProgram += "void main( void ){\n ";
+ fragmentProgram += "vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );\n";
+ fragmentProgram += alphaTestMethod;
+ fragmentProgram += "gl_FragColor = baseMap;\n";
+ fragmentProgram += "}";
+
+ textureShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ textureShaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+ }
+
+ setShaderProgram(textureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ setShaderAttributeSet(shaderAttributeSet);
+
+ }
+ else
+ {
+ if (color != null)
+ {
+ PolygonAttributes polyAtt = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0.0f);
+ polyAtt.setPolygonOffset(0.1f);
+ setPolygonAttributes(polyAtt);
+ LineAttributes lineAtt = new LineAttributes(1, LineAttributes.PATTERN_SOLID, false);
+ setLineAttributes(lineAtt);
+
+ ColoringAttributes colorAtt = new ColoringAttributes(color, ColoringAttributes.FASTEST);
+ setColoringAttributes(colorAtt);
+
+ RenderingAttributes ra = new RenderingAttributes();
+ ra.setIgnoreVertexColors(true);
+ setRenderingAttributes(ra);
+
+ Material mat = new Material();
+ setMaterial(mat);
+
+ if (colorLineShaderProgram == null)
+ {
+ colorLineShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance colorLineShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ colorLineShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ }
+
+ setShaderProgram(colorLineShaderProgram);
+
+ }
+ else
+ {
+ RenderingAttributes ra = new RenderingAttributes();
+ setRenderingAttributes(ra);
+
+ if (flatShaderProgram == null)
+ {
+ flatShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance flatShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ flatShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+
+ }
+
+ setShaderProgram(flatShaderProgram);
+
+ }
+ }
+
+ }
+
+ private static Shader[] makeShaders(String vertexProgram, String fragmentProgram)
+ {
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_VERTEX, vertexProgram) {
+ @Override
+ public String toString()
+ {
+ return "vertexProgram";
+ }
+ };
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_FRAGMENT, fragmentProgram) {
+ @Override
+ public String toString()
+ {
+ return "fragmentProgram";
+ }
+ };
+ return shaders;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/stencil/StencilOutline.java b/src/classes/org/jdesktop/j3d/examples/stencil/StencilOutline.java new file mode 100644 index 0000000..b339743 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/stencil/StencilOutline.java @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2016 JogAmp Community. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +package org.jdesktop.j3d.examples.stencil; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; + +import javax.swing.JOptionPane; + +import org.jdesktop.j3d.examples.Resources; +import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance; +import org.jogamp.java3d.Alpha; +import org.jogamp.java3d.AmbientLight; +import org.jogamp.java3d.Appearance; +import org.jogamp.java3d.Background; +import org.jogamp.java3d.BoundingSphere; +import org.jogamp.java3d.BranchGroup; +import org.jogamp.java3d.Canvas3D; +import org.jogamp.java3d.ColoringAttributes; +import org.jogamp.java3d.DirectionalLight; +import org.jogamp.java3d.GLSLShaderProgram; +import org.jogamp.java3d.GraphicsConfigTemplate3D; +import org.jogamp.java3d.Group; +import org.jogamp.java3d.LineAttributes; +import org.jogamp.java3d.Material; +import org.jogamp.java3d.Node; +import org.jogamp.java3d.PolygonAttributes; +import org.jogamp.java3d.RenderingAttributes; +import org.jogamp.java3d.RotationInterpolator; +import org.jogamp.java3d.Shader; +import org.jogamp.java3d.ShaderAppearance; +import org.jogamp.java3d.ShaderError; +import org.jogamp.java3d.ShaderErrorListener; +import org.jogamp.java3d.ShaderProgram; +import org.jogamp.java3d.Shape3D; +import org.jogamp.java3d.SourceCodeShader; +import org.jogamp.java3d.Transform3D; +import org.jogamp.java3d.TransformGroup; +import org.jogamp.java3d.loaders.IncorrectFormatException; +import org.jogamp.java3d.loaders.ParsingErrorException; +import org.jogamp.java3d.loaders.Scene; +import org.jogamp.java3d.loaders.objectfile.ObjectFile; +import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior; +import org.jogamp.java3d.utils.shader.StringIO; +import org.jogamp.java3d.utils.universe.PlatformGeometry; +import org.jogamp.java3d.utils.universe.SimpleUniverse; +import org.jogamp.java3d.utils.universe.ViewingPlatform; +import org.jogamp.vecmath.Color3f; +import org.jogamp.vecmath.Point3d; +import org.jogamp.vecmath.Vector3f; + +/** + * Simple Java 3D example program to display an .obj object with shader programs. + * And then add a stencil based outline around it + */ +public class StencilOutline extends javax.swing.JFrame +{ + + private String shaderName = "polkadot3d"; + private boolean spin = false; + private boolean noTriangulate = false; + private boolean noStripify = false; + private double creaseAngle = 60.0; + private URL filename = null; + + private SimpleUniverse univ = null; + private BranchGroup scene = null; + + public BranchGroup createSceneGraph() + { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.7); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + int flags = ObjectFile.RESIZE; + if (!noTriangulate) + flags |= ObjectFile.TRIANGULATE; + if (!noStripify) + flags |= ObjectFile.STRIPIFY; + ObjectFile f = new ObjectFile(flags, (float) (creaseAngle * Math.PI / 180.0)); + Scene s = null; + try + { + s = f.load(filename); + } + catch (FileNotFoundException e) + { + System.err.println(e); + System.exit(1); + } + catch (ParsingErrorException e) + { + System.err.println(e); + System.exit(1); + } + catch (IncorrectFormatException e) + { + System.err.println(e); + System.exit(1); + } + + // Set vertex and fragment shader program for all Shape3D nodes in scene + /* String vertexProgram = null; + String fragmentProgram = null; + try + { + vertexProgram = StringIO.readFully(new File( + System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + shaderName + ".vert")); + fragmentProgram = StringIO.readFully(new File( + System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + shaderName + ".frag")); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + Shader[] shaders = new Shader[2]; + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_VERTEX, vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_FRAGMENT, fragmentProgram); + ShaderProgram shaderProgram = new GLSLShaderProgram(); + + + shaderProgram.setShaders(shaders); + setShaderProgram(s.getSceneGroup(), shaderProgram);*/ + + setOutline(s.getSceneGroup()); + + objTrans.addChild(s.getSceneGroup()); + + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + + if (spin) + { + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 4000, 0, 0, 0, 0, 0); + + RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f, (float) Math.PI * 2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + } + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + return objRoot; + } + + private Canvas3D createUniverse() + { + // Critical!!! notice this is not using this call, but explicitly asks for a stencil buffer + //GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); + template.setStencilSize(16); + // Return the GraphicsConfiguration that best fits our needs. + GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice() + .getBestConfiguration(template); + + // Create a Canvas3D using the preferred configuration + Canvas3D canvas3d = new Canvas3D(config); + + // Create simple universe with view branch + univ = new SimpleUniverse(canvas3d); + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + + // Add a ShaderErrorListener + univ.addShaderErrorListener(new ShaderErrorListener() { + @Override + public void errorOccurred(ShaderError error) + { + error.printVerbose(); + JOptionPane.showMessageDialog(StencilOutline.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE); + } + }); + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = univ.getViewingPlatform(); + + PlatformGeometry pg = new PlatformGeometry(); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + pg.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f); + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + + DirectionalLight light1 = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + pg.addChild(light1); + + DirectionalLight light2 = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + pg.addChild(light2); + + viewingPlatform.setPlatformGeometry(pg); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + if (!spin) + { + OrbitBehavior orbit = new OrbitBehavior(canvas3d, OrbitBehavior.REVERSE_ALL); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + } + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return canvas3d; + } + + private static void usage() + { + System.out.println("Usage: java ObjLoadGLSL [-s] [-S shaderName] [-n] [-t] [-c degrees] <.obj file>"); + System.out.println(" -s Spin (no user interaction)"); + System.out.println(" -S Set shader name (default is 'simple')"); + System.out.println(" -n No triangulation"); + System.out.println(" -t No stripification"); + System.out.println(" -c Set crease angle for normal generation (default is 60 without"); + System.out.println(" smoothing group info, otherwise 180 within smoothing groups)"); + System.exit(0); + } // End of usage + + // Set shader program for all nodes in specified branch graph + private void setShaderProgram(BranchGroup g, ShaderProgram shaderProgram) + { + ShaderAppearance myApp = new ShaderAppearance(); + Material mat = new Material(); + myApp.setShaderProgram(shaderProgram); + myApp.setMaterial(mat); + setShaderProgram(g, myApp); + } + + // Recursively set shader program for all children of specified group + private void setShaderProgram(Group g, ShaderAppearance myApp) + { + + Enumeration<Node> e = g.getAllChildren(); + while (e.hasMoreElements()) + { + Node n = e.nextElement(); + if (n instanceof Group) + { + setShaderProgram((Group) n, myApp); + } + else if (n instanceof Shape3D) + { + Shape3D s = (Shape3D) n; + s.setAppearance(myApp); + } + } + } + + private Color3f c = new Color3f(1.0f, 1.0f, 0); + private int outlineStencilMask = (int) (c.x * 255) + (int) (c.y * 255) + (int) (c.z * 255); + + // Recursively set an outline onto all Shape3D nodes + private void setOutline(Group g) + { + + Enumeration<Node> e = g.getAllChildren(); + while (e.hasMoreElements()) + { + Node n = e.nextElement(); + if (n instanceof Group) + { + setOutline((Group) n); + } + else if (n instanceof Shape3D) + { + // start by giving the current appearance a rendering attribute + Shape3D s = (Shape3D) n; + System.out.println("outlining an shape "); + Appearance sapp = s.getAppearance(); + + // get and ensure rend atts exist + RenderingAttributes ra1 = sapp.getRenderingAttributes(); + if (ra1 == null) + { + ra1 = new RenderingAttributes(); + sapp.setRenderingAttributes(ra1); + } + + ra1.setStencilEnable(true); + ra1.setStencilWriteMask(outlineStencilMask); + ra1.setStencilFunction(RenderingAttributes.ALWAYS, outlineStencilMask, outlineStencilMask); + ra1.setStencilOp(RenderingAttributes.STENCIL_REPLACE, // + RenderingAttributes.STENCIL_REPLACE, // + RenderingAttributes.STENCIL_REPLACE); + + sapp.setRenderingAttributes(ra1); + + // now attach an outline shape + Shape3D outliner = new Shape3D(); + + //////////////////////////////// + //Outliner gear, note empty geom should be ignored + //Appearance app = new SimpleShaderAppearance(c); + Appearance app = new Appearance(); + + // lineAntialiasing MUST be true, to force this to be done during rendering pass (otherwise it's hidden) + LineAttributes la = new LineAttributes(4, LineAttributes.PATTERN_SOLID, true); + app.setLineAttributes(la); + PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_BACK, 0.0f, true, 0.0f); + app.setPolygonAttributes(pa); + ColoringAttributes colorAtt = new ColoringAttributes(c, ColoringAttributes.FASTEST); + app.setColoringAttributes(colorAtt); + + RenderingAttributes ra2 = new RenderingAttributes(); + ra2.setStencilEnable(true); + ra2.setStencilWriteMask(outlineStencilMask); + ra2.setStencilFunction(RenderingAttributes.NOT_EQUAL, outlineStencilMask, outlineStencilMask); + ra2.setStencilOp(RenderingAttributes.STENCIL_KEEP, // + RenderingAttributes.STENCIL_KEEP, // + RenderingAttributes.STENCIL_KEEP); + + // draw it even when hidden, which we don't want now + ra2.setDepthBufferEnable(false); + ra2.setDepthTestFunction(RenderingAttributes.ALWAYS); + + app.setRenderingAttributes(ra2); + + outliner.setAppearance(app); + + // use the same geometry ass teh shape we are outlining! + outliner.setGeometry(s.getGeometry()); + + g.addChild(outliner); + + } + } + } + + /** + * Creates new form ObjLoadGLSL + */ + public StencilOutline(String args[]) + { + if (args.length != 0) + { + for (int i = 0; i < args.length; i++) + { + if (args[i].startsWith("-")) + { + if (args[i].equals("-s")) + { + spin = true; + } + else if (args[i].equals("-n")) + { + noTriangulate = true; + } + else if (args[i].equals("-t")) + { + noStripify = true; + } + else if (args[i].equals("-c")) + { + if (i < args.length - 1) + { + creaseAngle = (new Double(args[++i])).doubleValue(); + } + else + usage(); + } + else if (args[i].equals("-S")) + { + if (i < args.length - 1) + { + shaderName = args[++i]; + } + else + usage(); + } + else + { + usage(); + } + } + else + { + try + { + if ((args[i].indexOf("file:") == 0) || (args[i].indexOf("http") == 0)) + { + filename = new URL(args[i]); + } + else if (args[i].charAt(0) != '/') + { + filename = new URL("file:./" + args[i]); + } + else + { + filename = new URL("file:" + args[i]); + } + } + catch (MalformedURLException e) + { + System.err.println(e); + System.exit(1); + } + } + } + } + + if (filename == null) + { + filename = Resources.getResource("resources/geometry/galleon.obj"); + if (filename == null) + { + System.err.println("resources/geometry/galleon.obj not found"); + System.exit(1); + } + } + + // Initialize the GUI components + initComponents(); + + // Create Canvas3D and SimpleUniverse; add canvas to drawing panel + Canvas3D c = createUniverse(); + drawingPanel.add(c, java.awt.BorderLayout.CENTER); + + // Create the content branch and add it to the universe + scene = createSceneGraph(); + univ.addBranchGraph(scene); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents + private void initComponents() + { + drawingPanel = new javax.swing.JPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("ObjLoadGLSL"); + drawingPanel.setLayout(new java.awt.BorderLayout()); + + drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700)); + getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER); + + pack(); + }// </editor-fold>//GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) + { + System.setProperty("sun.awt.noerasebackground", "true"); + + // DO I need this? does this default to true now? + System.setProperty("j3d.stencilClear", "true"); + + //System.setProperty("j3d.rend", "jogl2es2"); + + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() + { + StencilOutline objLoadGLSL = new StencilOutline(args); + objLoadGLSL.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + // End of variables declaration//GEN-END:variables + +} |