getAWTGraphicsConfiguration returns null error - java

I've been tasked with programming a camera in a 3D environment as a part of my CS course.
The purpose is to show how basic camera view transformations are calculated and displayed.
I've been trying to do it in javafx first, but it seems to me too 'high-level' for showing basic calculations.
Now I'm trying to make below java 3d code work on my machine (copied from here), just to see how it works. I split it in two classes as suggested by IDE:
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.LineStripArray;
import javax.media.j3d.Shape3D;
import javax.vecmath.Point3d;
public class tuval7 {
public tuval7() {
SimpleUniverse u = new SimpleUniverse();
BranchGroup group = new BranchGroup();
Point3d coords[] = new Point3d[4];
Appearance app = new Appearance();
coords[0] = new Point3d(-0.5d, -0.2d, 0.1d);
coords[1] = new Point3d(-0.2d, 0.1d, 0.0d);
coords[2] = new Point3d(0.2d, -0.3d, 0.1d);
coords[3] = new Point3d(0.3d, 0.5d, 0.10d);
int vertexCounts[] = {4};
LineStripArray lines = new LineStripArray(4,
GeometryArray.COORDINATES, vertexCounts);
lines.setCoordinates(0, coords);
Shape3D shape = new Shape3D(lines, app);
group.addChild(shape);
u.addBranchGraph(group);
u.getViewingPlatform().setNominalViewingTransform();
}
}
and
public class tuval1 {
public static void main(String[] args) {
new tuval7();
}
}
Initially I have installed old Java 3D from Oracle website, but after running into an issue with
incorrect bitness , I have added JARs to my library as per https://gouessej.wordpress.com/2012/08/01/java-3d-est-de-retour-java-3d-is-back/#netbeans, i.e. j3dcore.jar, j3dutils.jar, vecmath.jar, jogamp-fat.jar .
When run, I'm getting an NPE at a 'SimpleUniverse' line, that I don't know how to solve on my own:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.jogamp.nativewindow.awt.AWTGraphicsConfiguration.getAWTGraphicsConfiguration()" because "<local3>" is null
at javax.media.j3d.JoglPipeline.getGraphicsConfig(JoglPipeline.java:8291)
at javax.media.j3d.Canvas3D.getGraphicsConfig(Canvas3D.java:958)
at javax.media.j3d.Canvas3D.<init>(Canvas3D.java:1028)
at javax.media.j3d.Canvas3D.<init>(Canvas3D.java:990)
at com.sun.j3d.utils.universe.Viewer.<init>(Viewer.java:205)
at com.sun.j3d.utils.universe.Viewer.<init>(Viewer.java:151)
at com.sun.j3d.utils.universe.SimpleUniverse.<init>(SimpleUniverse.java:249)
at com.sun.j3d.utils.universe.SimpleUniverse.<init>(SimpleUniverse.java:211)
at com.sun.j3d.utils.universe.SimpleUniverse.<init>(SimpleUniverse.java:96)
at tuval7.<init>(tuval7.java:12)
at tuval1.main(tuval1.java:4)
Any hint on what <local3>is or what is the problem and how to solve that?
I'm using jdk-16.0.1 with NetBeans 12.4 on Windows 10 Pro Version 10.0.19042.
I would be thankful for:
A suggestion what Java libraries/extensions would be the simplest to use to program basic 3D camera behaviour. The scenery does not need to be complicated, e.g. just edges (lines) of a few rectangular cuboids would do. The point is to be able to show how camera view changes when rotating camera left/right or up/down or applying basic translations.
A solution to the NPE I'm getting, so that at least I could play a bit with these libraries.

Related

Are jfreechart-fx 1.0.1 charts interactable with or just an image built and presented by fxgraphics2d?

I am currently trying to figure out, howjfreechart's splitting into swing(1.5) and JavaFX (1.0.1) affects the JavaFX part. As far as I (very limited knowledge on this topic) understand The jfree-fx uses fxgraphics2d to draw its original swing components(?) into an FX-canvas to add this into JavaFX nodes.
Now my question is, if that fxgraphics2d object is still interactable with? I mean things like tooltips and scrolling and similar stuff normal jfreecharts offer. Since my knowledge and time is somewhat limited, I would want to know, if it is worth digging deeper into jfree-fx (if those charts are still interactable with) or if those charts are solely pictures of the actual chart and not interactable with. Then I would need to find a better solution.
I am currently learning how to build a candlestick chart within my java application. While I managed to build a chart only using JavaFX, its performance was really bad as soon as there were drawn some hundred candlesticks.
Then I came across jfreechart, of which I read, that its performance is well above the internal JavaFX charting possibilities. So today I managed to construct my first chart with jfreechart-fx and performance is quite ok. Further I find it much more intuitive to build those charts... but I am not sure if the jfree-fx version only prints images or real chart objects to the nodes. (I read somewhere something about converting a chart into an image to increase performance of drawing...)
Thank you for any information on that topic.
For example here is my JFreeChart Class, which is drawn correctly, but I just do not get any interaction with the chart with my mouse. E.g. I'd like to zoom in/out using the mousewheel and I'd like to pan the chart to the left/right by clickhold leftmouse. That why I am concerned that I am only looking at an image right now. All viable solutions I find through google seem to address only JFreeChart and not JFreeChart-FX.
package org.ezstrats.jfreeChart;
import javafx.collections.ObservableList;
import org.ezstrats.model.chartData.Candlestick;
import org.ezstrats.model.chartData.Chart;
import org.ezstrats.model.chartData.Exchange;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.HighLowItemLabelGenerator;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
public class JFreeCandlestickChart extends JPanel {
private static final DateFormat READABLE_TIME_FORMAT = new SimpleDateFormat("kk:mm:ss");
private OHLCSeries ohlcSeries;
private TimeSeries volumeSeries;
private JFreeChart candlestickChart;
public JFreeCandlestickChart(String title) {
ObservableList<Candlestick> candlesticks = Exchange.getCandlesticks();
// Create new chart
candlestickChart = createChart(title, candlesticks);
// Create new chart panel
final ChartPanel chartPanel = new ChartPanel(candlestickChart);
chartPanel.setPreferredSize(new Dimension(832, 468));
chartPanel.getChart().getXYPlot().getDomainAxis().setAutoRange(false);
chartPanel.getChart().getXYPlot().getDomainAxis().setLowerBound(candlesticks.get(candlesticks.size() - 300).getTimestampOpen());
chartPanel.getChart().getXYPlot().getDomainAxis().setUpperBound(candlesticks.get(candlesticks.size() - 1).getTimestampOpen());
// Enable zooming - not workign?! ...
chartPanel.setMouseZoomable(true);
chartPanel.setMouseWheelEnabled(true);
chartPanel.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
// process before
super.mouseDragged(e);
chartPanel.getChart().getXYPlot().getDomainAxis().configure();
// process after
}
});
add(chartPanel, BorderLayout.CENTER);
}
public JFreeChart createChart(String title, ObservableList<Candlestick> candlesticks){
/**
* 1st:
* Creating candlestick subplot
*/
// Create OHLCSeriesCollection as a price dataset for candlestick chart
OHLCSeriesCollection candlestickDataset = new OHLCSeriesCollection();
ohlcSeries = new OHLCSeries("Price");
candlestickDataset.addSeries(ohlcSeries);
// Create candlestick chart priceAxis
NumberAxis priceAxis = new NumberAxis("Price");
priceAxis.setAutoRangeIncludesZero(false);
// Create candlestick chart renderer
CandlestickRenderer candlestickRenderer = new CandlestickRenderer(CandlestickRenderer.WIDTHMETHOD_AVERAGE,
false,
new HighLowItemLabelGenerator(new SimpleDateFormat("kk:mm"), new DecimalFormat("0.00000000")));
// Create candlestickSubplot
XYPlot candlestickSubplot = new XYPlot(candlestickDataset, null, priceAxis, candlestickRenderer);
candlestickSubplot.setBackgroundPaint(Color.white);
/**
* 2nd:
* Creating volume subplot
*/
// creates TimeSeriesCollection as a volume dataset for volume chart
TimeSeriesCollection volumeDataset = new TimeSeriesCollection();
volumeSeries = new TimeSeries("Volume");
volumeDataset.addSeries(volumeSeries);
// Create volume chart volumeAxis
NumberAxis volumeAxis = new NumberAxis("Volume");
volumeAxis.setAutoRangeIncludesZero(true);
// Set to no decimal
volumeAxis.setNumberFormatOverride(new DecimalFormat("0"));
// Create volume chart renderer
XYBarRenderer timeRenderer = new XYBarRenderer();
timeRenderer.setShadowVisible(false);
timeRenderer.setDefaultToolTipGenerator(new StandardXYToolTipGenerator("Volume--> Time={1} Size={2}",
new SimpleDateFormat("kk:mm"), new DecimalFormat("0")));
// Create volumeSubplot
XYPlot volumeSubplot = new XYPlot(volumeDataset, null, volumeAxis, timeRenderer);
volumeSubplot.setBackgroundPaint(Color.white);
/**
* 3rd:
* Adding Candles to this chart
**/
for (Candlestick candle: candlesticks){
addCandleToChart(candle.getTimestampOpen(),
candle.getPriceOpen(),
candle.getPriceHigh(),
candle.getPriceLow(),
candle.getPriceClose(),
candle.getVolumeQuote());
}
/**
* 4th:
* Create chart main plot with two subplots (candlestickSubplot,
* volumeSubplot) and one common dateAxis
*/
// Creating charts common dateAxis
DateAxis dateAxis = new DateAxis("Time");
dateAxis.setDateFormatOverride(new SimpleDateFormat("dd.mm.yy kk:mm"));
//dateAxis.setRange();
// reduce the default left/right margin from 0.05 to 0.02
dateAxis.setLowerMargin(0.02);
dateAxis.setUpperMargin(0.02);
dateAxis.setLabelAngle(0);
// Create mainPlot
CombinedDomainXYPlot mainPlot = new CombinedDomainXYPlot(dateAxis);
mainPlot.setGap(10.0);
mainPlot.add(candlestickSubplot, 4);
mainPlot.add(volumeSubplot, 1);
mainPlot.setOrientation(PlotOrientation.VERTICAL);
mainPlot.setDomainPannable(true);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, mainPlot, false);
//chart.removeLegend();
// Einbetten in JScrollPaenl??? um Scrollen zu ermöglichen...
// ChartPanel chartPanel = new ChartPanel(chart);
return chart;
}
/**
* Fill series with data.
*
* #param c opentime
* #param o openprice
* #param h highprice
* #param l lowprice
* #param c closeprice
* #param v volume
*/
private void addCandleToChart(long time, double o, double h, double l, double c, double v) {
// Add bar to the data. Let's repeat the same bar
FixedMillisecond t = new FixedMillisecond(time);
//READABLE_TIME_FORMAT.parse(String.valueOf(time)));
ohlcSeries.add(t, o, h, l, c);
volumeSeries.add(t, v);
}
public void setOhlcSeries(OHLCSeries ohlcSeries) {
this.ohlcSeries = ohlcSeries;
}
public void setVolumeSeries(TimeSeries volumeSeries) {
this.volumeSeries = volumeSeries;
}
public OHLCSeries getOhlcSeries() {
return ohlcSeries;
}
public TimeSeries getVolumeSeries() {
return volumeSeries;
}
public JFreeChart getCandlestickChart() {
return candlestickChart;
}
}
I haven't looked at jFreeChart in detail, but I think the main difference between it and the in-built JavaFX charting API is that jFreeChart uses a canvas for its implementation, whereas the in-built charts use the scene graph. Roughly, though not exactly, its similar to this definition of a retained mode (scene graph) vs immediate mode (canvas).
It's probably possible to add interactivity to canvas rendered graphics. It is likely technically challenging beyond basic whole-chart zoom and drag ops. Implementing or demonstrating the addition of such interactivity with canvas rendered graphics is beyond what I would be prepared to do within the context of a StackOverflow answer.
JFreeChart includes an interaction package:
https://github.com/jfree/jfreechart-fx/tree/master/src/main/java/org/jfree/chart/fx/interaction
I suggest you investigate the interaction package, try using it and see if it offers the level of interaction you need.
As Roger mentions in the comments, you can get some basic interaction on a JFreeChartFX chart by wrapping the chart in a ChartViewer using ChartViewer(JFreeChart myChart).
Related question:
How do I properly add a MouseHandler to my JFreeChart-FX to drag the chart from left to right
An aside on Canvas vs SceneGraph
This info on how canvas works is included so that you might have a better idea of what is going on here (note everything here may not be 100% correct, but is close enough to help understanding).
Technically, JavaFX only uses a SceneGraph for rendering. How canvas is internally implemented, as far as I understand, is that each canvas is a node in the scenegraph and comes with a command queue of drawing instructions. When you draw to the canvas, it doesn't draw immediately, instead it puts the drawing commands into a queue, then, at some point, before the next 60fps drawing pulse completes, it renders those to an image buffer that it relays into a JavaFX node. Old commands are forgotten by the canvas command queue once executed, so everything just ends up as pixels eventually. You can keep track of drawing commands within your application and re-issue them to repaint the canvas from scratch if you wish, but canvas won't help with that.
What JFreeChartFX is doing is providing an adapter which makes a JavaFX canvas look like a Swing painting surface, so that the heavy lifting and internal engine of JFreeChart can be used to issue all of the drawing commands, and those can be rendered to either a JavaFX canvas or Swing canvas depending upon the desired output UI tech.
If JFreeChart also provided a similar adapter for JavaFX events, rather than Swing events, and if JFreeChart already has a way to do interactivity using Swing events, then it could potentially add interactivity to JFreeChartFX using a similar adapter or replacement for Swing event mechanisms. Perhaps that is what the interaction package linked above is doing.

leaderboard for javafx game

Hello stackoverflow community! I am learning to program and am working on a "duck hunt" style javafx game for mobile devices where 3 types of ducks move horizontally across the screen. Each time a certain type of duck is clicked, that type of duck gets a point next to its name.
What I would like to do is display a global leaderboard after the game so you can see which type of duck was clicked the most out of everyone who has played the game. What is everyones preferred way of implementing something like this? If you have any questions please feel free to ask me. Thanks, -H.J.
Edit (4/20/16 1:40PM PST): Because my original post was put on hold because it was deemed to vague, I wrote up a very basic example program to help explain what I am trying to do. On my menu scene I would like to retrieve the total number of clicks on the red and green rectangles for everyone who has played this game worldwide, which is currently globalScoreRed and globalScoreGreen and set to 0 because this is one of the parts I need help with.
On the playGame scene, when you hit the GG button, I would like scoreRed and scoreGreen to be submitted to the leaderboard which would adjust the values when viewed from the menu screen.
This is a very bad game and I can attest is not a game I would enjoy playing, but I am trying to learn the concepts of how to send the values and retrieve them. Once again thanks for viewing my post and helping out, you are very much appreciated.
package LeaderboardHelp;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class LeaderboardHelpMain extends Application {
Stage window;
Scene menu, playGame;
private Rectangle targetRed = new Rectangle(40, 40);
private Rectangle targetGreen = new Rectangle(40, 40);
private int scoreRed = 0;
private int scoreGreen = 0;
private Text redScoreText = new Text("Red: " + scoreRed);
private Text greenScoreText = new Text("Green: " + scoreGreen);
private int globalScoreRed = 0;
private int globalScoreGreen = 0;
private Text globalRedScoreText = new Text("Worldwide Red Clicks: " + globalScoreRed);
private Text globalGreenScoreText = new Text("Worldwide Green Clicks: " + globalScoreGreen);
private boolean playable = false;
public static void main(String[] args) { launch(args); }
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
Button startButton = new Button("Start!");
startButton.setOnAction(e -> window.setScene(playGame));
//menu scene layout
VBox menuLayout = new VBox(20);
menuLayout.getChildren().addAll(globalGreenScoreText, globalRedScoreText, startButton);
menu = new Scene(menuLayout, 600, 600);
Button ggButton = new Button("GG");
ggButton.setOnAction(e -> window.setScene(menu));
targetRed.setFill(Color.RED);
targetRed.setOnMouseClicked(event -> {
scoreRed += 1;
redScoreText.setText("Red: " + scoreRed);
});
targetGreen.setFill(Color.GREEN);
targetGreen.setOnMouseClicked(event -> {
scoreGreen += 1;
greenScoreText.setText("Green: " + scoreGreen);
});
targetRed.setTranslateX(50);
targetRed.setTranslateY(50);
targetGreen.setTranslateX(100);
targetGreen.setTranslateY(50);
greenScoreText.setTranslateX(500);
greenScoreText.setTranslateY(50);
redScoreText.setTranslateX(500);
redScoreText.setTranslateY(70);
ggButton.setTranslateX(250);
ggButton.setTranslateY(250);
//game layout
Pane gameLayout = new Pane();
gameLayout.getChildren().addAll(targetRed, targetGreen, redScoreText, greenScoreText, ggButton);
playGame = new Scene(gameLayout, 600, 600);
window.setScene(menu);
window.setTitle("Leaderboard Helper");
window.show();
}
}
Edit (4/20/16 8:45PM PST) So after more reading I came across oracles EchoServer example which is getting me on a track (not sure if its right or wrong track). I was thinking about having the server save the submitted scores in a text file. When the menu scene is called by client it will connect to the server and request the scores. The server will read the text file and send scores to the application client. When the GG button is pressed, the score is sent to the server which reads the text file, adds the news score to old score and then overwrites the score text file. Is there a better way of doing this? I do want this to be scalable allowing lots of users to add their score at the same time.
A web service would be required. A simple one that takes maybe the type of duck and the number of times it was clicked.
POST /duck/{type}/{clicks}
The web-service would need to be secured using HTTPS or HMAC, or better yet both.
For HMAC the key would need to be hidden and obfuscated in your code. Security is always breakable, its about making the effort not worth it for such a small payout to any would-be hacker.
To do HMAC properly one should use a NONCE when creating the digest (aka signature). The NONCE should have a short expiration time. Many implementations use the timestamp as a NONCE, other implementations have the NONCE being provided by the web service. For simplicity I would go with the former. If the NONCE is older than 2 or 3 seconds, then reject the request.

JavaPlot and gnuplot

I'm desperately trying to get Java and gnuplot to play nice. I've started using JavaPlot and have added the jar to the classpath (using Eclipse).
I've also downloaded gnuplot and have placed it in a safe place.
First question, all examples given by JavaPlot are assuming you have put gnuplot in the right place, where this is I have no idea. Therefore their example of:
import com.panayotis.gnuplot.JavaPlot;
public class test {
public static void main(String[] args) {
JavaPlot p = new JavaPlot();
p.addPlot("sin(x)");
p.plot();
}
}
Will only work if gnuplot is added to the classpath, any ideas on where that might be and how?
Not to worry though, as you can define the location of gnuplot in the constructor of JavaPlot, like so:
import com.panayotis.gnuplot.JavaPlot;
public class test {
public static void main(String[] args) {
JavaPlot p = new JavaPlot("D:/Eclipse/gnuplot/binary/pgnuplot.exe");
p.addPlot("sin(x)");
p.plot();
}
}
This does something, if you're quick you can see a graph appear (correctly, can see the sine wave) and then immediately disappear. I've read online that in the actual gnuplot application this is common when using Windows and that a '-persist' must be added after the plot. Fortunately JavaPlot also has a function that does that:
p.setPersist(true);
But in my case it does nothing. So second question, anyone used gnuplot, JavaPlot, and Windows 7 64bit before and know how to do this? From my Googling I understand pgnuplot is the correct .exe to run?
What am I missing? What am I doing wrong?
I think I may have a workaround for you, as I ran into the same sort of thing today when accessing JavaPlot on Windows 7 (32 bit here though). Yes, pgnuplot.exe is the one you want, however you do not need to explicitly setPersist if you do not want to because JavaPlot does that for you. What I had to do was go through the source code and comment out a line.
In GnuPlotParameters, I see the code
/* Finish! */
bf.append("quit").append(NL);
This is lines 198-199. Then the plot windows stays open. Now, what this also does is leave open gnuplot. If you do not mind, you can see your graphs this way. Have not figured out yet how to close gnuplot while leaving the plot window open.
EDIT:
Maybe a more appropriate way is not to comment out line 199 and go with this:
bf.append("pause -1").append(NL);
/* Finish! */
bf.append("quit").append(NL);
In this manner, the pause dialog comes up. This allows you to see the plot. When you dismiss the dialog, everything goes bye-bye.
Try JavaGnuplotHybrid: https://github.com/mleoking/JavaGnuplotHybrid
It solves the problem of immediately disappear.
Here is the example for a 2D plot:
public void plot2d() {
JGnuplot jg = new JGnuplot();
Plot plot = new Plot("") {
{
xlabel = "x";
ylabel = "y";
}
};
double[] x = { 1, 2, 3, 4, 5 }, y1 = { 2, 4, 6, 8, 10 }, y2 = { 3, 6, 9, 12, 15 };
DataTableSet dts = plot.addNewDataTableSet("2D Plot");
dts.addNewDataTable("y=2x", x, y1);
dts.addNewDataTable("y=3x", x, y2);
jg.execute(plot, jg.plot2d);
}
I use eclipse for debugging and happen to be using this package. I figured out how to fix this. Add the following to your code. The setPersist(true) doesn't seem to work for some reason.
p.set("term", "x11 persist");
try this
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("D:/Projet/X-Gnuplot_4.6.0_rev6/Bin/gnuplot/bin/gnuplot.exe");
java.io.OutputStream opStream = proc.getOutputStream();
PrintWriter gp = new PrintWriter(new BufferedWriter(new OutputStreamWriter(opStream)));
gp.println("plot sin(x); pause mouse close;\n");
gp.close();
int exitVal = proc.waitFor();
System.out.println("Exited with error code "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
it works for me
replace your
p.addPlot("sin(x)");
by
p.addPlot("sin(x); pause 100;");
it only appears for 100 seconds
fsd

How do i create a movie from a set of images using qtj and java?

I have a set of images i want to add one after another and create a movie. I will be using Quicktime for java for this(I'm on a mac).
I searched the web i have found lots of examples that show how to play movies using qtj, but i can't find any code snippets or tutorials showing how i can create a movie frame by frame using qtj?
I've done this through QTJ with the MovieMaker class from processing libraries (GPL). Processing is pure java, though it can hide it for beginners.
Small tutorial:
Download Processing, open it, go to Sketch -> Show Sketch Folder, create a folder called "data", and put all your images inside that folder, named "filename01.gif" through "filename09.gif". Paste the following code into the editor, and hit play:
/**
* Makes a QuickTime movie out of an array of images.
*/
import processing.video.*;
MovieMaker mm;
PImage[] imageFrames;
int index;
void setup() {
size(320, 240);
int numFrames = 9;
imageFrames = new PImage[numFrames];
for( int i = 0; i < imageFrames.length; i++ )
{
imageFrames[i] = loadImage( "filename" + nf(i+1,2) + ".gif" );
}
// Save uncompressed, at 15 frames per second
mm = new MovieMaker(this, width, height, "drawing.mov");
// Or, set specific compression and frame rate options
//mm = new MovieMaker(this, width, height, "drawing.mov", 30,
// MovieMaker.ANIMATION, MovieMaker.HIGH);
}
void draw() {
if( index < imageFrames.length )
{
// show the image
image( imageFrames[index], 0, 0 );
// Add window's pixels to movie
mm.addFrame();
index++;
}
else
{
mm.finish();
// Quit running the sketch once the file is written
exit();
}
}
This will create a file "drawing.mov" from your images in the sketch folder. If you go to file --> export application, and then open the sketch folder and navigate to the folder application.macosx/source or application.windows/source, there should be a .java file that has the actual code, which should look like this:
import processing.core.*;
import processing.xml.*;
import processing.video.*;
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
public class movie2 extends PApplet {
/**
* Makes a QuickTime movie out of an array of images.
*/
MovieMaker mm;
PImage[] imageFrames;
int index;
public void setup() {
size(320, 240);
int numFrames = 9;
imageFrames = new PImage[numFrames];
for( int i = 0; i < imageFrames.length; i++ )
{
imageFrames[i] = loadImage( "filename" + nf(i+1,2) + ".gif" );
}
// Save uncompressed, at 15 frames per second
mm = new MovieMaker(this, width, height, "drawing.mov");
// Or, set specific compression and frame rate options
//mm = new MovieMaker(this, width, height, "drawing.mov", 30,
// MovieMaker.ANIMATION, MovieMaker.HIGH);
}
public void draw() {
if( index < imageFrames.length )
{
// show the image
image( imageFrames[index], 0, 0 );
// Add window's pixels to movie
mm.addFrame();
index++;
}
else
{
mm.finish();
// Quit running the sketch once the file is written
//exit();
println( "done" );
}
}
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#e0dfe3", "movie2" });
}
}
To use pure java, you'll need to use core.jar and video.jar from the processing application folder on your classpath, and then compile this java code. Here's a function reference and a javadoc for the processing library. Here are the javadocs for the MovieMaker class. If you want, you can see the source to the MovieMaker class.
HTH
There is an export related piece of sample code here:
http://developer.apple.com/samplecode/ImportExport/listing1.html
It shows how a single native QuickTime Movie can be opened for reading and then be passed on to a MovieExporter component to create a new QuickTime Movie from it.
For the code to import a file for as source for writing, see
void importMedia()
For the code to export the source to a QuickTime Movie, see
void run()
It should be possible to open an image file using the same approach, though, as long as the file format of the input file is supported by QuickTime (like f.e. BMP).
You should be able to write a sequence of image files using most of this code as well.
The only point which you will have to investigate is which method you'll have to call to append additional frames to an existing Movie. It might work using the same API, but most likely you'll need to use another call.
If you have to dig for another method you should be able to find it in the QT Java Reference Documentation located here:
http://developer.apple.com/Java/Reference/1.4/Java14API_QTJ/
It's a hack and most likely poor in performance, but it might actually work.
And... I never tried this (I am a QuickTime for Windows guy by trade) so: sorry, no warranty = ).
Edit: If you are looking for a way to write frames to a QT Movie using an existing input buffer instead of reading the data from file using the QT API, there should be APIs for
this as well. Just check out the reference documentation.
Edit 2: Actually it might be worthwhile to check out the C/C++ API Documentation here, as naming of components and calls seems to follow roughly the same naming conventions (i.e. this might help to dig for the calls of the Java API you need) and the C/C++ Docs seem to be more thorough in terms of providing Guides and How To's as a starting point. The C/C++ Docs can be found here:
http://developer.apple.com/referencelibrary/QuickTime/index.html
The most interesting sections should be
Import & Export
Compression & Decompression
Have Fun!

What is the best OpenGL java binding? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am trying to achieve better performance for my Java SWT application, and I just found out it is possible to use OpenGL in SWT. It seems there are more than one Java binding for OpenGL. Which one do you prefer?
Note that I have never used OpenGL before, and that the application needs to work on Windows, Linux and Mac OS X.
I'd suggest checking out LWJGL, the LightWeight Java Game Library. It's got OpenGL bindings, but it also has OpenAL bindings and some great tutorials to get you started.
Just keep in mind that Swing/SWT and OpenGL are generally used for entirely different things. You may end up wanting to use a combination of both. Just try LWJGL out and see how well it fits with what you're doing.
JOGL
My reasons can be quoted off the previously linked site:
JOGL provides full access to the APIs in the OpenGL 2.0 specification as well as nearly all vendor extensions, and integrates with the AWT and Swing widget sets.
Also if you want to have some fun learning and poking around, Processing is an excellent way to start (Processing also uses JOGL btw...)
JOGL is probably the only option worth considering.
Notice that there are at least two options for integrating it into an SWT application. There's a GLCanvas that belongs to SWT and a GLCanvas that belongs to AWT.
The one in SWT is not feature complete and is not really maintained. It's much better to use the AWT GLCanvas inside a SWT_AWT container.
Some code from a recent project:
import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.events.*;
public class Main implements GLEventListener
{
public static void main(String[] args)
{
Display display = new Display();
Main main = new Main();
main.runMain(display);
display.dispose();
}
void runMain(Display display)
{
final Shell shell = new Shell(display);
shell.setText("Q*bert 3D - OpenGL Exercise");
GridLayout gridLayout = new GridLayout();
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
shell.setLayout(gridLayout);
// this allows us to set particular properties for the GLCanvas
GLCapabilities glCapabilities = new GLCapabilities();
glCapabilities.setDoubleBuffered(true);
glCapabilities.setHardwareAccelerated(true);
// instantiate the canvas
final GLCanvas canvas = new GLCanvas(glCapabilities);
// we can't use the default Composite because using the AWT bridge
// requires that it have the property of SWT.EMBEDDED
Composite composite = new Composite(shell, SWT.EMBEDDED);
GridData ld = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(ld);
// set the internal layout so our canvas fills the whole control
FillLayout clayout = new FillLayout();
composite.setLayout(clayout);
// create the special frame bridge to AWT
java.awt.Frame glFrame = SWT_AWT.new_Frame(composite);
// we need the listener so we get the GL events
canvas.addGLEventListener(this);
// finally, add our canvas as a child of the frame
glFrame.add(canvas);
// show it all
shell.open();
// the event loop.
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
}
JOGL will give you best performance and portability. But be aware that learning JOGL, which is essentially the same as learning OpenGL, is not easy.
Personally, I'm not even aware of Java bindings for OpenGL other than JOGL -- I think JOGL is pretty much the standard for Java OpenGL.
It works in Windows, Linux, and OS X, but you might want to read over the official documentation for some notes about specific issues in each platform.
Keep in mind that the OpenGL paradigm is quite different from Swing/AWT or the Java 2D API; OpenGL is not a drop-in replacement for Swing.
We've had lots of luck at work using JOGL. The new 2.0 version is at http://jogamp.org/ (the last "old" version is at http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/).
For JOGL 2 with SWT specifically, I've got a series of tutorials starting at http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/ that demonstrates exactly how to make cross-platform JOGL SWT applications, complete with installable native binaries.
Or if you don't want to use Eclipse RCP, here's an even simpler example that just draws one triangle with JOGL 2 and SWT. To build it, put it in a project with swt.jar (from http://www.eclipse.org/swt/) and the latest JOGL autobuild .jar and .dll files (from http://jogamp.org/). The only problem with this simple example is that it won't be cross-platform without some extra help -- you need the ability that Eclipse RCP gives you to bundle multiple sets of platform libraries together into one project.
package name.wadewalker.onetriangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import javax.media.opengl.GL;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GL2;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.glu.GLU;
public class OneTriangle {
public static void main(String [] args) {
GLProfile.initSingleton( true );
GLProfile glprofile = GLProfile.get( GLProfile.GL2 );
Display display = new Display();
Shell shell = new Shell( display );
shell.setLayout( new FillLayout() );
Composite composite = new Composite( shell, SWT.NONE );
composite.setLayout( new FillLayout() );
GLData gldata = new GLData();
gldata.doubleBuffer = true;
// need SWT.NO_BACKGROUND to prevent SWT from clearing the window
// at the wrong times (we use glClear for this instead)
final GLCanvas glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
glcanvas.setCurrent();
final GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();
// fix the viewport when the user resizes the window
glcanvas.addListener( SWT.Resize, new Listener() {
public void handleEvent(Event event) {
setup( glcanvas, glcontext );
}
});
// draw the triangle when the OS tells us that any part of the window needs drawing
glcanvas.addPaintListener( new PaintListener() {
public void paintControl( PaintEvent paintevent ) {
render( glcanvas, glcontext );
}
});
shell.setText( "OneTriangle" );
shell.setSize( 640, 480 );
shell.open();
while( !shell.isDisposed() ) {
if( !display.readAndDispatch() )
display.sleep();
}
glcanvas.dispose();
display.dispose();
}
private static void setup( GLCanvas glcanvas, GLContext glcontext ) {
Rectangle rectangle = glcanvas.getClientArea();
glcanvas.setCurrent();
glcontext.makeCurrent();
GL2 gl = glcontext.getGL().getGL2();
gl.glMatrixMode( GL2.GL_PROJECTION );
gl.glLoadIdentity();
// coordinate system origin at lower left with width and height same as the window
GLU glu = new GLU();
glu.gluOrtho2D( 0.0f, rectangle.width, 0.0f, rectangle.height );
gl.glMatrixMode( GL2.GL_MODELVIEW );
gl.glLoadIdentity();
gl.glViewport( 0, 0, rectangle.width, rectangle.height );
glcontext.release();
}
private static void render( GLCanvas glcanvas, GLContext glcontext ) {
Rectangle rectangle = glcanvas.getClientArea();
glcanvas.setCurrent();
glcontext.makeCurrent();
GL2 gl = glcontext.getGL().getGL2();
gl.glClear( GL.GL_COLOR_BUFFER_BIT );
// draw a triangle filling the window
gl.glLoadIdentity();
gl.glBegin( GL.GL_TRIANGLES );
gl.glColor3f( 1, 0, 0 );
gl.glVertex2f( 0, 0 );
gl.glColor3f( 0, 1, 0 );
gl.glVertex2f( rectangle.width, 0 );
gl.glColor3f( 0, 0, 1 );
gl.glVertex2f( rectangle.width / 2, rectangle.height );
gl.glEnd();
glcanvas.swapBuffers();
glcontext.release();
}
}

Categories

Resources