Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8123554

Scene snapshot and Group snapshot do not work as expected

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Duplicate
    • Affects Version/s: 8
    • Fix Version/s: 8
    • Component/s: javafx
    • Labels:

      Description

      I am trying to use snapshot to create a picture file of JavaFX3D displays.
      First I tried scene.snapshot(null). Most tests produced a blank png file.
      One test produced a tiny part of the display.
      Next I tried group.snapshot( ) with SnapshotParameters. Eventually I
      got a picture with more of the display. It was only part of the display
      and the colors were all wrong and it is the wrong size..
      Attached is a sample program.
      It is setup to use wi = scene.snapshot(null);
      Next try
            SnapshotParameters sp = new SnapshotParameters();
            sp.setViewport(new Rectangle2D(0,0,600,700));
      // sp.setDepthBuffer(true);
          try {
      // wi = scene.snapshot(null);
              wi = root.snapshot(sp,null);
      Lastly try
            SnapshotParameters sp = new SnapshotParameters();
      // sp.setViewport(new Rectangle2D(0,0,600,700));
      // sp.setDepthBuffer(true);
          try {
      // wi = scene.snapshot(null);
            wi = root.snapshot(sp,null);

      setDepthBuffer(true) had no effect.
      I also do not understand why Scene snapshot is different from Group snapshot

      Regards
      Don
      --------------
      package javafx3d;
      import java.awt.image.BufferedImage;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;

      import javax.imageio.ImageIO;
      import javax.vecmath.Point3f;
      import javax.vecmath.TexCoord2f;
      import javax.vecmath.Tuple2f;
      import javax.vecmath.Tuple3f;

      import javafx.application.Application;
      import javafx.embed.swing.SwingFXUtils;
      import javafx.event.EventHandler;
      import javafx.geometry.Rectangle2D;
      import javafx.scene.Group;
      import javafx.scene.PerspectiveCamera;
      import javafx.scene.PointLight;
      import javafx.scene.Scene;
      import javafx.scene.SnapshotParameters;
      import javafx.scene.image.Image;
      import javafx.scene.image.WritableImage;
      import javafx.scene.input.KeyCode;
      import javafx.scene.input.KeyEvent;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.Pane;
      import javafx.scene.paint.Color;
      import javafx.scene.paint.PhongMaterial;
      import javafx.scene.shape.MeshView;
      import javafx.scene.shape.Sphere;
      import javafx.scene.shape.TriangleMesh;
      import javafx.scene.transform.Rotate;
      import javafx.stage.Stage;
       
      public class SmoothCylinderC extends Application {
       
        double anchorX, anchorY, anchorAngle;
        Scene scene;
        Stage stage;
       
        private PerspectiveCamera addCamera(Scene scene) {
          PerspectiveCamera perspectiveCamera = new PerspectiveCamera(false);
          scene.setCamera(perspectiveCamera);
          return perspectiveCamera;
        }
       
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
          launch(args);
        }
       
        @Override
        public void start(Stage primaryStage) {
          stage = primaryStage;
          primaryStage.setTitle("Smooth Cylinder and Cone");

          final PhongMaterial redMaterial = new PhongMaterial();
          redMaterial.setSpecularColor(Color.ORANGE);
          redMaterial.setDiffuseColor(Color.RED);
       
          Cylinder cylinder = new Cylinder();
          MeshView red = cylinder.build(200f,300f,101);
      // Image rimage = textureloader("Textures\\stone11.png");
          red.setMaterial(redMaterial);
          red.setTranslateX(250);
          red.setTranslateY(250);
          red.setTranslateZ(450);
      // redMaterial.setBumpMap(rimage);
          
          final PhongMaterial yellowMaterial = new PhongMaterial();
          yellowMaterial.setDiffuseColor(Color.YELLOW);
          yellowMaterial.setSpecularColor(Color.LIGHTYELLOW);
          Cone cone = new Cone();
          MeshView yellow = cone.build(200f,300f,101);
      // Image yimage = textureloader("Textures\\stone11.png");
          yellow.setMaterial(yellowMaterial);
          yellow.setTranslateX(250);
          yellow.setTranslateY(250);
          yellow.setTranslateZ(50);
      // yellowMaterial.setBumpMap(yimage);

          final Group parent = new Group(red,yellow);
      // final Group parent = new Group();

          parent.setTranslateZ(500);
          parent.setRotationAxis(Rotate.Y_AXIS);

          LightCubeA lc = new LightCubeA();
          lc.build(300);
      // lc.add(parent);
          Group lcg = new Group();
          lc.add(lcg);
          lcg.setTranslateX(250);
          lcg.setTranslateY(250);
          lcg.setTranslateZ(500);
       
          final Group root = new Group(parent,lcg);

       
          final Scene scene = new Scene(root, 600, 700, true);
      /*
          scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override public void handle(KeyEvent event) {
              if ((event.getCode() == KeyCode.C) &&
                (event.isControlDown())) {
                stage.close();
                System.exit(0);
              }
            }
          });
          
          scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent event) {
              parent.setRotate(anchorAngle + anchorX - event.getSceneX());
            }
          });
      */
          PointLight pointLight = new PointLight(Color.ANTIQUEWHITE);
          pointLight.setTranslateX(-500);
          pointLight.setTranslateY(-10);
          pointLight.setTranslateZ(-500);
       
          root.getChildren().add(pointLight);
       
          addCamera(scene);
          primaryStage.setScene(scene);
          primaryStage.show();
          
          WritableImage wi;
          BufferedImage bi;
          File f;
          FileOutputStream fos;
      // SnapshotParameters sp = new SnapshotParameters();
      // sp.setViewport(new Rectangle2D(0,0,600,700));
      // sp.setDepthBuffer(true);
          try {
            wi = scene.snapshot(null);
      // wi = root.snapshot(sp,null);
            System.out.println(wi.getWidth()+","+wi.getHeight());
            bi = SwingFXUtils.fromFXImage(wi, null);
            f = new File("saveimage.png");
            fos = new FileOutputStream(f);
            ImageIO.write(bi, "png", fos);
            fos.close();
          } catch(Exception e) {
            e.printStackTrace();
            wi = null;
          }

        }
        public Image textureloader(String fnam) {
          Image image;
          File f;
          FileInputStream fis;
          try {
            f = new File(fnam);
            fis = new FileInputStream(f);
            image = new Image(fis);
            fis.close();
          } catch(Exception e) {
            System.out.println("textureloader "+e.getMessage());
            image = null;
          }
          return(image);
        }
        public class Cylinder {
          public MeshView build(float r,float h,int pts) {
            TriangleMesh tm = new TriangleMesh();
            MeshView mv = new MeshView(tm);
            int[] idxa;
            int[] fsg;
            float[] txs;
            Point3f[] tcir,bcir;
            Point3f[] cyl;
            float[] cps;
            int[] idx = {0,0,1,1,0,1};
            TexCoord2f[] tcd;
            int i,j,n;
            boolean diag = false;
      /*
       * build points on cylinder
       */
            RotRtns rr = new RotRtns();
            tcir = rr.circle(r,h/2f,pts+1);
            bcir = rr.circle(r,-h/2f,pts+1);
            cyl = new Point3f[pts*6];
            n = 0;
            for (i = 0;i < pts;i++) {
              cyl[n++] = bcir[idx[0]+i];
              cyl[n++] = tcir[idx[1]+i];
              cyl[n++] = bcir[idx[2]+i];
              cyl[n++] = bcir[idx[3]+i];
              cyl[n++] = tcir[idx[4]+i];
              cyl[n++] = tcir[idx[5]+i];
            }
      /*
       * build texture points for cylinder
       */
            tcd = texcds(r,h,pts);
      /*
       * build arrays for mesh
       */
            n = pts * 2;
            idxa = new int[n*6];
            j = 0;
            for (i = 0;i < n*6;i+=2) { // face indices
              idxa[i] = j; idxa[i+1] = j++;
            }
            fsg = new int[n];
            for (i = 0;i < n;i++) fsg[i] = 1; // face smoothing
            VecMathPlus vmp = new VecMathPlus();
            cps = vmp.Tuple3f2float(cyl); // vertices
            txs = vmp.Tuple2f2float(tcd); // texcoords
      /*
       * setPoints
       */
            if (diag) {
              System.out.println("coordinates = "+cps.length);
              for (i = 0;i < cps.length;i+=3) {
                for (j = 0;j < 3;j++) {
                  System.out.print(cps[i+j]+",");
                }
                System.out.println();
              }
            }
            tm.getPoints().setAll(cps);
      /*
       * setTexCoords
       */
            if (diag) {
              System.out.println("texcoords = "+txs.length);
              for (i = 0;i < txs.length;i+=2) {
                for (j = 0;j < 2;j++) {
                  System.out.print(txs[i+j]+",");
                }
                System.out.println();
              }
            }
            tm.getTexCoords().setAll(txs);
      /*
       * setFaces
       */
            if (diag) {
              System.out.println("faces = "+idxa.length);
              for (i = 0;i < idxa.length;i++) {
                System.out.print(idxa[i]+",");
              }
              System.out.println();
            }
            tm.getFaces().setAll(idxa);
      /*
       * setSmoothing
       */
            if (diag) {
              System.out.println("fsgs = "+fsg.length);
              for (i = 0;i < fsg.length;i++) {
                System.out.print(fsg[i]+",");
              }
              System.out.println();
            }
            tm.getFaceSmoothingGroups().setAll(fsg);

            return(mv);
          }
          TexCoord2f[] texcds(float r,float h,int pts) {
            TexCoord2f[] tcd;
            float a,b;
            int i,n;
            tcd = new TexCoord2f[pts*6];
            a = (r+r) * 3.14159f / (float) pts;
            n = 0;
            for (i = 0;i < pts;i++) {
              b = a * (float) i;
              tcd[n++] = new TexCoord2f(b,-h/2f);
              tcd[n++] = new TexCoord2f(b,h/2f);
              tcd[n++] = new TexCoord2f(b+a,-h/2f);
              tcd[n++] = new TexCoord2f(b+a,-h/2f);
              tcd[n++] = new TexCoord2f(b,h/2f);
              tcd[n++] = new TexCoord2f(b+a,h/2f);
            }
            for (i = 0;i < tcd.length;i++) tcd[i].scale(.005f);
            return(tcd);
          }
        }
        public class Cone {
          public MeshView build(float r,float h,int pts) {
            TriangleMesh tm = new TriangleMesh();
            MeshView mv = new MeshView(tm);
            int[] idxa;
            int[] fsg;
            float[] txs;
            Point3f[] bcir;
            Point3f[] con;
            Point3f top;
            float[] cps;
            TexCoord2f[] tcd;
            int i,j,n;
            boolean diag = false;
      /*
       * build points on cone
       */
            RotRtns rr = new RotRtns();
            bcir = rr.circle(r,h/2f,pts+1);
            con = new Point3f[pts*3];
            n = 0;
            top = new Point3f(0,-h/2f,0);
            for (i = 0;i < pts;i++) {
              con[n++] = top;
              con[n++] = bcir[i];
              con[n++] = bcir[i+1];
            }
      /*
       * build texture points for cone
       */
            tcd = texcds(r,h,pts);
      /*
       * build arrays for mesh
       */
            n = pts * 2;
            idxa = new int[n*3];
            j = 0;
            for (i = 0;i < n*3;i+=2) { // face indices
              idxa[i] = j; idxa[i+1] = j++;
            }
            fsg = new int[pts];
            for (i = 0;i < pts;i++) fsg[i] = 1; // face smoothing
            VecMathPlus vmp = new VecMathPlus();
            cps = vmp.Tuple3f2float(con); // vertices
            txs = vmp.Tuple2f2float(tcd); // texcoords
      /*
       * setPoints
       */
            if (diag) {
              System.out.println("coordinates = "+cps.length);
              for (i = 0;i < cps.length;i+=3) {
                for (j = 0;j < 3;j++) {
                  System.out.print(cps[i+j]+",");
                }
                System.out.println();
              }
            }
            tm.getPoints().setAll(cps);
      /*
       * setTexCoords
       */
            if (diag) {
              System.out.println("texcoords = "+txs.length);
              for (i = 0;i < txs.length;i+=2) {
                for (j = 0;j < 2;j++) {
                  System.out.print(txs[i+j]+",");
                }
                System.out.println();
              }
            }
            tm.getTexCoords().setAll(txs);
      /*
       * setFaces
       */
            if (diag) {
              System.out.println("faces = "+idxa.length);
              for (i = 0;i < idxa.length;i++) {
                System.out.print(idxa[i]+",");
              }
              System.out.println();
            }
            tm.getFaces().setAll(idxa);
      /*
       * setSmoothing
       */
            if (diag) {
              System.out.println("fsgs = "+fsg.length);
              for (i = 0;i < fsg.length;i++) {
                System.out.print(fsg[i]+",");
              }
              System.out.println();
            }
            tm.getFaceSmoothingGroups().setAll(fsg);

            return(mv);
          }
          TexCoord2f[] texcds(float r,float h,int pts) {
            TexCoord2f[] tcd;
            float a,b,c;
            int i,n;
            tcd = new TexCoord2f[pts*3];
            a = (r+r) * 3.14159f / (float) pts;
            c = a * 0.5f;
            n = 0;
            for (i = 0;i < pts;i++) {
              b = a * (float) i;
              tcd[n++] = new TexCoord2f(b+c,h/2f);
              tcd[n++] = new TexCoord2f(b,-h/2f);
              tcd[n++] = new TexCoord2f(b+a,-h/2f);
            }
            for (i = 0;i < tcd.length;i++) tcd[i].scale(.005f);
            return(tcd);
          }
        }
        public class VecMathPlus {
          public float[] Tuple3f2float(Tuple3f[] p3f) {
            float[] pts;
            int i,k,n;
          
            k = p3f.length;
            pts = new float[k*3];
            n = 0;
            for (i = 0;i < k;i++){
              pts[n++] = p3f[i].x;
              pts[n++] = p3f[i].y;
              pts[n++] = p3f[i].z;
            }
            return(pts);
          }
          public float[] Tuple2f2float(Tuple2f[] p3f) {
            float[] pts;
            int i,k,n;
          
            k = p3f.length;
            pts = new float[k*2];
            n = 0;
            for (i = 0;i < k;i++){
              pts[n++] = p3f[i].x;
              pts[n++] = p3f[i].y;
            }
            return(pts);
          }
        }
        public class RotRtns {
          public Point3f[] circle(float r,float h,int pts) {
            Point3f[] cir;
            double fts;
            double tpi;
            double a;
            int i;
      /*
       * built points on circle
       */
            cir = new Point3f[pts];
            fts = (pts - 1);
            tpi = Math.PI * 2.0;
            for (i = 0;i < (pts-1);i++) {
              a = tpi * (double) i / fts;
              cir[i] = new Point3f();
              cir[i].x = r * (float) Math.cos(a);
              cir[i].z = r * (float) Math.sin(a);
              cir[i].y = h;
            }
            cir[pts-1] = cir[0];
            return(cir);
          }
        }
        public class LightCubeA {
          PointLight[] plc = new PointLight[8];
          Sphere[] sph = new Sphere[8];
      // Color[] cl = {Color.color(0,0,1),Color.color(0, 1, 0),Color.color(0,1,1),Color.color(1,0,0),
          Color[] cl = {Color.color(1,1,1),Color.color(1, 1, 1),Color.color(1,1,1),Color.color(1,0,0),
                        Color.color(1,0,1),Color.color(1,1,0),Color.color(1,0,.5),Color.color(1,.5,0),
          };
          PhongMaterial[] pm = new PhongMaterial[8];
          boolean[] onoff = {false,false,false,false,true,true,true,false,false,false,false,false};
      // boolean[] onoff = {true,true,true,true,true,true,true,true};
          double[][] pt = {{-1,-1,-1},{-1,-1, 1},{-1, 1,-1},{-1, 1, 1},
                           { 1,-1,-1},{ 1,-1, 1},{ 1, 1,-1},{ 1, 1, 1}
          };
          public void build(double siz) {
            int i;
            
            for (i = 0;i < 8;i++) {
              plc[i] = new PointLight(cl[i]);
              plc[i].setTranslateX(pt[i][0]*siz);
              plc[i].setTranslateY(pt[i][1]*siz);
              plc[i].setTranslateZ(pt[i][2]*siz);
              plc[i].setLightOn(onoff[i]);
              pm[i] = new PhongMaterial();
              pm[i].setSpecularColor(cl[i]);
              pm[i].setDiffuseColor(cl[i]);
              sph[i] = new Sphere(30);
              sph[i].setMaterial(pm[i]);
              sph[i].setTranslateX(pt[i][0]*siz);
              sph[i].setTranslateY(pt[i][1]*siz);
              sph[i].setTranslateZ(pt[i][2]*siz);
            }
          }
          public void add(Group gp) {
            int i;
            for (i = 0;i < 8;i++) gp.getChildren().add(plc[i]);
            for (i = 0;i < 8;i++) gp.getChildren().add(sph[i]);
          }
        }
      }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              kcr Kevin Rushforth
              Reporter:
              dscalesjfx Don Scales (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Imported: