Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Smoother Animation
Smoother Animation [message #455418] |
Fri, 13 May 2005 19:50 |
PB Messages: 1 Registered: July 2009 |
Junior Member |
|
|
I have written two snippets that perform a simple animation in SWT and
AWT. The AWT version uses the full screen mode and a page-flipping
BufferStrategy (the code doesn't actually force this, it just does this by
default on my h/w and WinXP - I've tried to keep the code minimal). The
SWT version resizes a Shell upto full screen and just paints. It
optionally double-buffers (a trivial copy operation is kept out of the
painting when double-buffering which probably doesn't save much under the
hood).
The AWT version is markedly smoother than the SWT version. In fact, the
SWT version is unusable. The code is as minimal as I could get it to show
the problem I have.
Can anyone suggest any changes to the SWT version to make the animation as
smooth as the AWT version? Do I have to go to OpenGL?
Thanks.
P.S. I've included the imports for the SWT version, as it uses both AWT
and SWT objects and obviously the import choice has to be right.
AWT version:
public class Viewer {
Image bigImage;
GraphicsDevice device;
public static void main(String[] args) {
new Viewer().run();
}
public void run() {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
device = env.getDefaultScreenDevice();
GraphicsConfiguration gc = device.getDefaultConfiguration();
Frame frame = new Frame(gc);
frame.setUndecorated(true);
frame.setIgnoreRepaint(true);
device.setFullScreenWindow(frame);
frame.setVisible(true);
Rectangle bounds = gc.getBounds();
makeBigImage(frame, bounds);
frame.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent arg0) {
finish();
}
});
frame.createBufferStrategy(2);
BufferStrategy bufferStrategy = frame.getBufferStrategy();
int offsetX = 0;
while (offsetX < bigImage.getWidth(frame) - bounds.width) {
Graphics g = bufferStrategy.getDrawGraphics();
if (!bufferStrategy.contentsLost()) {
g.drawImage(bigImage, 0,
0,
bounds.width,
bounds.height, offsetX, 0,
offsetX + bounds.width,
bounds.height, frame);
bufferStrategy.show();
g.dispose();
offsetX += 6;
}
}
}
private void finish() {
device.setFullScreenWindow(null);
System.exit(0);
}
private void makeBigImage(Frame frame, Rectangle bounds) {
Point bigImageDims = new Point(bounds.width * 4, bounds.height);
bigImage = frame.createImage(bigImageDims.x, bigImageDims.y);
GradientPaint gradient = new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow, true);
Graphics2D bigImageGraphics = (Graphics2D) bigImage.getGraphics();
bigImageGraphics.setPaint(gradient);
for (int x = 0; x < bigImageDims.x - 60; x += 60) {
for (int y = 0; y < bigImageDims.y - 60; y += 60) {
bigImageGraphics.fillOval(x, y, 50, 50);
}
}
bigImageGraphics.dispose();
}
}
SWT version:
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Viewer {
Display display;
Image bigImage, buffer;
Rectangle screenSize;
GC gc, bufferGC;
boolean doubleBuffering;
public static void main(String[] args) {
new Viewer().run();
}
public void run() {
doubleBuffering = true;
display = Display.getDefault();
Shell shell = new Shell(display, SWT.NO_BACKGROUND);
screenSize = display.getBounds();
shell.setBounds(screenSize);
shell.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent arg0) {
finish();
}
});
shell.open();
shell.forceFocus();
gc = new GC(shell);
makeBigImage();
buffer = new Image(display, screenSize.width, screenSize.height);
bufferGC = new GC(buffer);
new MoveIt().start();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
class MoveIt extends Thread {
public void run() {
int offset = 0;
int stopAt = bigImage.getImageData().width - screenSize.width;
while (offset < stopAt) {
if (doubleBuffering) {
bufferGC.drawImage(bigImage, offset += 3, 0, screenSize.width,
screenSize.height, 0, 0, screenSize.width,
screenSize.height);
gc.drawImage(buffer, 0, 0);
}
else {
gc.drawImage(bigImage, offset += 3, 0, screenSize.width,
screenSize.height, 0, 0, screenSize.width,
screenSize.height);
}
}
finish();
}
}
private void finish() {
buffer.dispose();
bigImage.dispose();
gc.dispose();
bufferGC.dispose();
display.dispose();
System.exit(0);
}
private void makeBigImage() {
Point bigImageDims = new Point(screenSize.width * 4, screenSize.height);
BufferedImage bufferedBigImage = new BufferedImage(bigImageDims.x,
bigImageDims.y, BufferedImage.TYPE_INT_ARGB);
GradientPaint gradient = new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow, true);
Graphics2D bigImageGraphics = (Graphics2D) bufferedBigImage
.getGraphics();
bigImageGraphics.setPaint(gradient);
for (int x = 0; x < bigImageDims.x - 60; x += 60) {
for (int y = 0; y < bigImageDims.y - 60; y += 60) {
bigImageGraphics.fillOval(x, y, 50, 50);
}
}
bigImageGraphics.dispose();
// Stuff to convert AWT image to SWT image
int[] data = ((DataBufferInt) bufferedBigImage.getRaster()
.getDataBuffer()).getData();
ImageData imageData = new ImageData(bigImageDims.x, bigImageDims.y, 32,
new PaletteData(0xFF0000, 0xFF00, 0xFF));
imageData.setPixels(0, 0, bigImageDims.x * bigImageDims.y, data, 0);
bigImage = new Image(display, imageData);
}
}
|
|
|
Re: Smoother Animation [message #455486 is a reply to message #455418] |
Mon, 16 May 2005 23:25 |
Steve Northover Messages: 1636 Registered: July 2009 |
Senior Member |
|
|
So I played with your code a bit and found that the step size for the AWT
code was 6 while the SWT was 3. After changing this and getting rid of the
SWT double buffering, the times were closer (AWT was still somewhat faster).
If you run the code in a shell that is 512x512 rather than full screen, then
SWT was faster. For me, the AWT animation was jerky and the SWT animation
was smooth but perhaps we are looking at different things? The AWT one
paused slighty now and again. Could be my graphics card? So it seems that
switching to full screen mode rather than running in a shell is faster (not
much of a surprise there). Do you need to run in full screen mode?
"PB" <pbamford@gmail.com> wrote in message
news:640c9ea3b3b71d195ec50fbd2c18c185$1@www.eclipse.org...
> I have written two snippets that perform a simple animation in SWT and
> AWT. The AWT version uses the full screen mode and a page-flipping
> BufferStrategy (the code doesn't actually force this, it just does this by
> default on my h/w and WinXP - I've tried to keep the code minimal). The
> SWT version resizes a Shell upto full screen and just paints. It
> optionally double-buffers (a trivial copy operation is kept out of the
> painting when double-buffering which probably doesn't save much under the
> hood).
>
> The AWT version is markedly smoother than the SWT version. In fact, the
> SWT version is unusable. The code is as minimal as I could get it to show
> the problem I have.
>
> Can anyone suggest any changes to the SWT version to make the animation as
> smooth as the AWT version? Do I have to go to OpenGL?
>
> Thanks.
>
> P.S. I've included the imports for the SWT version, as it uses both AWT
> and SWT objects and obviously the import choice has to be right.
>
> AWT version:
>
> public class Viewer {
> Image bigImage;
> GraphicsDevice device;
> public static void main(String[] args) {
> new Viewer().run();
> }
>
> public void run() {
> GraphicsEnvironment env = GraphicsEnvironment
> .getLocalGraphicsEnvironment();
> device = env.getDefaultScreenDevice();
> GraphicsConfiguration gc = device.getDefaultConfiguration();
> Frame frame = new Frame(gc);
> frame.setUndecorated(true);
> frame.setIgnoreRepaint(true);
> device.setFullScreenWindow(frame);
> frame.setVisible(true);
> Rectangle bounds = gc.getBounds();
> makeBigImage(frame, bounds);
> frame.addMouseListener(new MouseAdapter() {
> public void mouseClicked(MouseEvent arg0) {
> finish();
> }
> });
> frame.createBufferStrategy(2);
> BufferStrategy bufferStrategy = frame.getBufferStrategy();
>
> int offsetX = 0;
> while (offsetX < bigImage.getWidth(frame) - bounds.width) {
> Graphics g = bufferStrategy.getDrawGraphics();
> if (!bufferStrategy.contentsLost()) {
> g.drawImage(bigImage, 0,
> 0,
> bounds.width,
> bounds.height, offsetX, 0,
> offsetX + bounds.width,
> bounds.height, frame);
> bufferStrategy.show();
> g.dispose();
> offsetX += 6;
> }
> }
> }
>
> private void finish() {
> device.setFullScreenWindow(null);
> System.exit(0);
> }
>
> private void makeBigImage(Frame frame, Rectangle bounds) {
> Point bigImageDims = new Point(bounds.width * 4, bounds.height);
> bigImage = frame.createImage(bigImageDims.x, bigImageDims.y);
> GradientPaint gradient = new GradientPaint(0, 0, Color.red, 175, 175,
> Color.yellow, true);
> Graphics2D bigImageGraphics = (Graphics2D) bigImage.getGraphics();
> bigImageGraphics.setPaint(gradient);
> for (int x = 0; x < bigImageDims.x - 60; x += 60) {
> for (int y = 0; y < bigImageDims.y - 60; y += 60) {
> bigImageGraphics.fillOval(x, y, 50, 50);
> }
> }
> bigImageGraphics.dispose();
> }
> }
>
>
> SWT version:
>
> import java.awt.Color;
> import java.awt.GradientPaint;
> import java.awt.Graphics2D;
> import java.awt.image.BufferedImage;
> import java.awt.image.DataBufferInt;
>
> import org.eclipse.swt.SWT;
> import org.eclipse.swt.events.MouseAdapter;
> import org.eclipse.swt.events.MouseEvent;
> import org.eclipse.swt.graphics.GC;
> import org.eclipse.swt.graphics.Image;
> import org.eclipse.swt.graphics.ImageData;
> import org.eclipse.swt.graphics.PaletteData;
> import org.eclipse.swt.graphics.Point;
> import org.eclipse.swt.graphics.Rectangle;
> import org.eclipse.swt.widgets.Display;
> import org.eclipse.swt.widgets.Shell;
>
> public class Viewer {
> Display display;
>
> Image bigImage, buffer;
>
> Rectangle screenSize;
>
> GC gc, bufferGC;
>
> boolean doubleBuffering;
>
> public static void main(String[] args) {
> new Viewer().run();
> }
>
> public void run() {
>
> doubleBuffering = true;
>
> display = Display.getDefault();
> Shell shell = new Shell(display, SWT.NO_BACKGROUND);
> screenSize = display.getBounds();
> shell.setBounds(screenSize);
> shell.addMouseListener(new MouseAdapter() {
> public void mouseDoubleClick(MouseEvent arg0) {
> finish();
> }
> });
>
> shell.open();
> shell.forceFocus();
> gc = new GC(shell);
> makeBigImage();
> buffer = new Image(display, screenSize.width, screenSize.height);
> bufferGC = new GC(buffer);
>
> new MoveIt().start();
> while (!shell.isDisposed()) {
> if (!display.readAndDispatch())
> display.sleep();
> }
>
> }
>
> class MoveIt extends Thread {
> public void run() {
> int offset = 0;
> int stopAt = bigImage.getImageData().width - screenSize.width;
> while (offset < stopAt) {
> if (doubleBuffering) {
> bufferGC.drawImage(bigImage, offset += 3, 0, screenSize.width,
> screenSize.height, 0, 0, screenSize.width,
> screenSize.height);
> gc.drawImage(buffer, 0, 0);
> }
> else {
> gc.drawImage(bigImage, offset += 3, 0, screenSize.width,
> screenSize.height, 0, 0, screenSize.width,
> screenSize.height);
> }
> }
> finish();
> }
> }
>
> private void finish() {
> buffer.dispose();
> bigImage.dispose();
> gc.dispose();
> bufferGC.dispose();
> display.dispose();
> System.exit(0);
> }
>
> private void makeBigImage() {
> Point bigImageDims = new Point(screenSize.width * 4, screenSize.height);
> BufferedImage bufferedBigImage = new BufferedImage(bigImageDims.x,
> bigImageDims.y, BufferedImage.TYPE_INT_ARGB);
> GradientPaint gradient = new GradientPaint(0, 0, Color.red, 175, 175,
> Color.yellow, true);
> Graphics2D bigImageGraphics = (Graphics2D) bufferedBigImage
> .getGraphics();
> bigImageGraphics.setPaint(gradient);
> for (int x = 0; x < bigImageDims.x - 60; x += 60) {
> for (int y = 0; y < bigImageDims.y - 60; y += 60) {
> bigImageGraphics.fillOval(x, y, 50, 50);
> }
> }
> bigImageGraphics.dispose();
>
> // Stuff to convert AWT image to SWT image
> int[] data = ((DataBufferInt) bufferedBigImage.getRaster()
> .getDataBuffer()).getData();
> ImageData imageData = new ImageData(bigImageDims.x, bigImageDims.y, 32,
> new PaletteData(0xFF0000, 0xFF00, 0xFF));
> imageData.setPixels(0, 0, bigImageDims.x * bigImageDims.y, data, 0);
> bigImage = new Image(display, imageData);
> }
> }
>
>
>
>
>
>
|
|
| |
Goto Forum:
Current Time: Fri Apr 26 09:57:20 GMT 2024
Powered by FUDForum. Page generated in 0.02644 seconds
|