diff --git a/examples/org.eclipse.swt.examples/src/examples_graphics.properties b/examples/org.eclipse.swt.examples/src/examples_graphics.properties index 7165e3f993..2b76d314bd 100644 --- a/examples/org.eclipse.swt.examples/src/examples_graphics.properties +++ b/examples/org.eclipse.swt.examples/src/examples_graphics.properties @@ -226,3 +226,15 @@ TwisterDescription=This is a miscellaneous demonstration of an animated twister Wave=Wave WaveDescription=This is a miscellaneous demonstration of an animated wave effect with multiple motion patterns cycling through four different wave algorithms. + +Dancing=Dancing +DancingDescription=This is a miscellaneous demonstration of an animated isometric dancing shape with sine-wave deformations across a grid of polygons. + +BumpMapping=Bump Mapping +BumpMappingDescription=This is a miscellaneous demonstration of an animated bump mapping effect with a moving light source illuminating a textured surface. + +FlatText=Flat Text +FlatTextDescription=This is a miscellaneous demonstration of an animated flat text perspective distortion effect using sine/cosine rotation on a tiled texture. + +Lens=Lens +LensDescription=This is a miscellaneous demonstration of an animated spherical lens distortion effect that bounces across an image, magnifying the area beneath the lens. diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/BumpMappingTab.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/BumpMappingTab.java new file mode 100644 index 0000000000..eaaf403c20 --- /dev/null +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/BumpMappingTab.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2018 Laurent Caron and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Laurent Lepinay - Original Version + * Laurent Caron (laurent.caron at gmail dot com) - Conversion to SWT + * IBM Corporation - adaptation to GraphicsExample + *******************************************************************************/ + +package org.eclipse.swt.examples.graphics; + +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.RGB; + +/** + * This tab displays an animated bump mapping effect with a moving light source + * illuminating a textured surface. + */ +public class BumpMappingTab extends AnimatedGraphicsTab { + + private ImageData bumpImage; + private int[] envMap; + private float fTime; + private int lightX, lightY; + private ImageData imageData; + private Image outputImage; + private int imgWidth, imgHeight; + + public BumpMappingTab(GraphicsExample example) { + super(example); + } + + @Override + public String getCategory() { + return GraphicsExample.getResourceString("Misc"); //$NON-NLS-1$ + } + + @Override + public String getText() { + return GraphicsExample.getResourceString("BumpMapping"); //$NON-NLS-1$ + } + + @Override + public String getDescription() { + return GraphicsExample.getResourceString("BumpMappingDescription"); //$NON-NLS-1$ + } + + @Override + public int getInitialAnimationTime() { + return 10; + } + + @Override + public void dispose() { + if (outputImage != null) { + outputImage.dispose(); + outputImage = null; + } + } + + @Override + public void next(int width, int height) { + if (bumpImage == null) { + return; + } + + for (int y = 1; y < imgHeight - 1; y++) { + for (int x = 1; x < imgWidth - 1; x++) { + int dX = (bumpImage.getPixel(x + 1, y) >> 16) - (bumpImage.getPixel(x - 1, y) >> 16); + int dY = (bumpImage.getPixel(x, y + 1) >> 16) - (bumpImage.getPixel(x, y - 1) >> 16); + + dX = dX - (lightX - x); + dY = dY - (lightY - y); + if (dX <= -128 || dX >= 128) { + dX = dY = -128; + } + if (dY <= -128 || dY >= 128) { + dX = dY = -128; + } + dX += 128; + dY += 128; + + imageData.setPixel(x, y, envMap[dX + 256 * dY]); + } + } + + lightX = (int) (imgWidth / 2 + 80 * Math.cos(fTime += .1)); + lightY = (int) (imgHeight / 2 + 80 * Math.sin(fTime)); + } + + @Override + public void paint(GC gc, int width, int height) { + if (!example.checkAdvancedGraphics()) return; + + if (bumpImage == null) { + Image sourceImage = example.loadImage(gc.getDevice(), "bump.png"); //$NON-NLS-1$ + if (sourceImage == null) return; + bumpImage = sourceImage.getImageData(); + imgWidth = bumpImage.width; + imgHeight = bumpImage.height; + + envMap = new int[256 * 256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + envMap[x + 256 * y] = (int) (255 - 255 * Math.sqrt((x - 128) * (x - 128) + (y - 128) * (y - 128)) / Math.sqrt(128 * 128 + 128 * 128)); + } + } + + RGB[] colors = new RGB[256]; + for (int i = 0; i < 64; i++) { + colors[i] = new RGB(0, 0, 0); + } + for (int i = 64; i < 128; i++) { + colors[i] = new RGB(0, 0, (i - 64) * 4); + } + for (int i = 128; i < 256; i++) { + colors[i] = new RGB((i - 128) * 2, (i - 128) * 2, 255); + } + + fTime = 0.0f; + lightX = (int) (imgWidth / 2 + 80 * Math.cos(fTime)); + lightY = (int) (imgHeight / 2 + 80 * Math.sin(fTime)); + + imageData = new ImageData(imgWidth, imgHeight, 8, new PaletteData(colors)); + } + + if (imageData == null) { + return; + } + + if (outputImage != null) { + outputImage.dispose(); + } + outputImage = new Image(gc.getDevice(), imageData); + + int x = (width - imgWidth) / 2; + int y = (height - imgHeight) / 2; + gc.drawImage(outputImage, x, y); + } +} diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/DancingTab.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/DancingTab.java new file mode 100644 index 0000000000..86a50dff14 --- /dev/null +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/DancingTab.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2018 Laurent Caron and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Guillaume Bouchon (bouchon_guillaume@yahoo.fr) - Original Version + * Laurent Caron (laurent.caron at gmail dot com) - Conversion to SWT + * IBM Corporation - adaptation to GraphicsExample + *******************************************************************************/ + +package org.eclipse.swt.examples.graphics; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; + +/** + * This tab displays an animated isometric dancing shape with sine-wave + * deformations across a grid of polygons. + */ +public class DancingTab extends AnimatedGraphicsTab { + + private int pw, ph; + private float[][] pointsX; + private float[][] pointsY; + private float[][] pointsZ; + private double dec; + private int cw, ch, dx; + private int waveCx, waveCy; + private Image offscreenImage; + private int lastWidth, lastHeight; + + public DancingTab(GraphicsExample example) { + super(example); + } + + @Override + public String getCategory() { + return GraphicsExample.getResourceString("Misc"); //$NON-NLS-1$ + } + + @Override + public String getText() { + return GraphicsExample.getResourceString("Dancing"); //$NON-NLS-1$ + } + + @Override + public String getDescription() { + return GraphicsExample.getResourceString("DancingDescription"); //$NON-NLS-1$ + } + + @Override + public int getInitialAnimationTime() { + return 10; + } + + @Override + public void dispose() { + if (offscreenImage != null) { + offscreenImage.dispose(); + offscreenImage = null; + } + } + + @Override + public void next(int width, int height) { + if (pointsX == null || width != lastWidth || height != lastHeight) { + init(width, height); + } + dec += 0.25; + for (int x = 0; x < pw; x++) { + for (int y = 0; y < ph; y++) { + pointsX[x][y] = x * cw + y * dx; + pointsZ[x][y] = (float) (-Math.sin(dec + 1.5 * Math.sqrt((x - waveCx) * (x - waveCx) + (y - waveCy) * (y - waveCy)) + ch) * dx); + pointsY[x][y] = y * ch - pointsZ[x][y]; + } + } + } + + @Override + public void paint(GC gc, int width, int height) { + if (pointsX == null) { + init(width, height); + } + + gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(0, 0, width, height); + + if (offscreenImage != null) { + offscreenImage.dispose(); + } + offscreenImage = new Image(gc.getDevice(), width, height); + GC imageGC = new GC(offscreenImage); + imageGC.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); + imageGC.fillRectangle(0, 0, width, height); + imageGC.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_BLACK)); + + int xc = ph / 2 * dx; + int[] p = new int[8]; + + for (int x = 0; x < pw - 1; x++) { + for (int y = 0; y < ph - 1; y++) { + int gray = 255 / ph * y; + Color color = new Color(gray, gray, gray); + imageGC.setBackground(color); + + p[0] = (int) (pointsX[x][y] - xc); + p[2] = (int) (pointsX[x + 1][y] - xc); + p[4] = (int) (pointsX[x + 1][y + 1] - xc); + p[6] = (int) (pointsX[x][y + 1] - xc); + + p[1] = (int) pointsY[x][y]; + p[3] = (int) pointsY[x + 1][y]; + p[5] = (int) pointsY[x + 1][y + 1]; + p[7] = (int) pointsY[x][y + 1]; + + imageGC.fillPolygon(p); + } + } + imageGC.dispose(); + + gc.drawImage(offscreenImage, 0, 0); + } + + private void init(int width, int height) { + lastWidth = width; + lastHeight = height; + cw = 15; + ch = 15; + dx = 10; + + pw = width / cw; + ph = height / ch; + if (pw < 2) pw = 2; + if (ph < 2) ph = 2; + + waveCx = pw / 2; + waveCy = ph / 2; + + pointsX = new float[pw][ph]; + pointsY = new float[pw][ph]; + pointsZ = new float[pw][ph]; + dec = 0; + } +} diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/FlatTextTab.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/FlatTextTab.java new file mode 100644 index 0000000000..3c3e90486c --- /dev/null +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/FlatTextTab.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2018 Laurent Caron and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Josh83 - Original Version + * Laurent Caron (laurent.caron at gmail dot com) - Conversion to SWT + * IBM Corporation - adaptation to GraphicsExample + *******************************************************************************/ + +package org.eclipse.swt.examples.graphics; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; + +/** + * This tab displays an animated flat text perspective distortion effect + * using sine/cosine rotation on a tiled texture. + */ +public class FlatTextTab extends AnimatedGraphicsTab { + + private static final int HAUTEUR = 100; + + private int[] tex; + private int[] sine; + private int[] cose; + private double ang; + private int yd; + private ImageData imageData; + private ImageData textureData; + private Image outputImage; + private boolean initialized; + + public FlatTextTab(GraphicsExample example) { + super(example); + } + + @Override + public String getCategory() { + return GraphicsExample.getResourceString("Misc"); //$NON-NLS-1$ + } + + @Override + public String getText() { + return GraphicsExample.getResourceString("FlatText"); //$NON-NLS-1$ + } + + @Override + public String getDescription() { + return GraphicsExample.getResourceString("FlatTextDescription"); //$NON-NLS-1$ + } + + @Override + public int getInitialAnimationTime() { + return 10; + } + + @Override + public void dispose() { + if (outputImage != null) { + outputImage.dispose(); + outputImage = null; + } + } + + @Override + public void next(int width, int height) { + if (!initialized) { + return; + } + + int a = (int) (HAUTEUR * 0.625); + int b = HAUTEUR * 100; + + ang += 2f; + yd += 5; + + int angnew = (int) (ang - ((int) (ang / 256) << 8)); + int halfH = height / 2; + int halfW = width / 2; + + for (int y = 0; y < halfH; y++) { + for (int x = 0; x < width; x++) { + int u = a * (x - halfW) / (y - halfH); + int v = b / (y - halfH); + + int unew = (u * cose[angnew] - v * sine[angnew] >> 8); + int vnew = (u * sine[angnew] + v * cose[angnew] >> 8) + yd; + + int index = unew + (vnew << 8) & 65535; + imageData.setPixel(x, height - y - 1, tex[index]); + } + } + } + + @Override + public void paint(GC gc, int width, int height) { + if (!example.checkAdvancedGraphics()) return; + + if (!initialized) { + Image sourceImage = example.loadImage(gc.getDevice(), "TEXFLAT2.png"); //$NON-NLS-1$ + if (sourceImage == null) return; + textureData = sourceImage.getImageData(); + + tex = new int[65536]; + textureData.getPixels(0, 0, 65536, tex, 0); + + sine = new int[256]; + cose = new int[256]; + for (int i = 0; i < 256; i++) { + sine[i] = (int) (Math.sin(i * 0.02454) * 256); + cose[i] = (int) (Math.cos(i * 0.02454) * 256); + } + + yd = 0; + ang = 0; + + imageData = new ImageData(width, height, textureData.depth, textureData.palette); + initialized = true; + } + + if (imageData.width != width || imageData.height != height) { + imageData = new ImageData(width, height, textureData.depth, textureData.palette); + } + + if (outputImage != null) { + outputImage.dispose(); + } + outputImage = new Image(gc.getDevice(), imageData); + gc.drawImage(outputImage, 0, 0); + } +} diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/GraphicsExample.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/GraphicsExample.java index c0dea63661..67477fe2a2 100644 --- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/GraphicsExample.java +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/GraphicsExample.java @@ -491,6 +491,10 @@ GraphicsTab[] createTabs() { new ShadeBobsTab(this), new TwisterTab(this), new WaveTab(this), + new DancingTab(this), + new BumpMappingTab(this), + new FlatTextTab(this), + new LensTab(this), }; } diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/LensTab.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/LensTab.java new file mode 100644 index 0000000000..d038ecb7e6 --- /dev/null +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/LensTab.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2018 Laurent Caron and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * W.P. van Paassen and Byron Ellacott - Original Version + * Laurent Caron (laurent.caron at gmail dot com) - Conversion to SWT + * IBM Corporation - adaptation to GraphicsExample + *******************************************************************************/ + +package org.eclipse.swt.examples.graphics; + +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; + +/** + * This tab displays an animated spherical lens distortion effect that bounces + * across an image, magnifying the area beneath the lens. + */ +public class LensTab extends AnimatedGraphicsTab { + + private static final int LENS_WIDTH = 150; + private static final int LENS_ZOOM = 40; + + private ImageData backing; + private int[][] lens; + private int lensX = 16, lensY = 16; + private int xd = 1, yd = 1; + private ImageData imageData; + private Image outputImage; + private int imgWidth, imgHeight; + + public LensTab(GraphicsExample example) { + super(example); + } + + @Override + public String getCategory() { + return GraphicsExample.getResourceString("Misc"); //$NON-NLS-1$ + } + + @Override + public String getText() { + return GraphicsExample.getResourceString("Lens"); //$NON-NLS-1$ + } + + @Override + public String getDescription() { + return GraphicsExample.getResourceString("LensDescription"); //$NON-NLS-1$ + } + + @Override + public int getInitialAnimationTime() { + return 10; + } + + @Override + public void dispose() { + if (outputImage != null) { + outputImage.dispose(); + outputImage = null; + } + } + + @Override + public void next(int width, int height) { + if (backing == null) { + return; + } + + applyLens(lensX, lensY); + + lensX += xd; + lensY += yd; + if (lensX > imgWidth - LENS_WIDTH - 15 || lensX < 15) { + xd = -xd; + } + if (lensY > imgHeight - LENS_WIDTH - 15 || lensY < 15) { + yd = -yd; + } + } + + @Override + public void paint(GC gc, int width, int height) { + if (!example.checkAdvancedGraphics()) return; + + if (backing == null) { + Image sourceImage = example.loadImage(gc.getDevice(), "tuxblackbg.png"); //$NON-NLS-1$ + if (sourceImage == null) return; + backing = sourceImage.getImageData(); + imgWidth = backing.width; + imgHeight = backing.height; + + initLens(); + + imageData = new ImageData(imgWidth, imgHeight, backing.depth, backing.palette); + int[] pixels = new int[imgWidth * imgHeight]; + backing.getPixels(0, 0, imgWidth * imgHeight, pixels, 0); + imageData.setPixels(0, 0, imgWidth * imgHeight, pixels, 0); + } + + if (imageData == null) { + return; + } + + if (outputImage != null) { + outputImage.dispose(); + } + outputImage = new Image(gc.getDevice(), imageData); + + int x = (width - imgWidth) / 2; + int y = (height - imgHeight) / 2; + gc.drawImage(outputImage, x, y); + } + + private void initLens() { + lens = new int[LENS_WIDTH][LENS_WIDTH]; + int r = LENS_WIDTH / 2; + int d = LENS_ZOOM; + + for (int y = 0; y < LENS_WIDTH >> 1; y++) { + for (int x = 0; x < LENS_WIDTH >> 1; x++) { + int ix, iy, offset; + if (x * x + y * y < r * r) { + float shift = (float) (d / Math.sqrt(d * d - (x * x + y * y - r * r))); + ix = (int) (x * shift - x); + iy = (int) (y * shift - y); + } else { + ix = 0; + iy = 0; + } + offset = iy * imgWidth + ix; + lens[LENS_WIDTH / 2 - y][LENS_WIDTH / 2 - x] = -offset; + lens[LENS_WIDTH / 2 + y][LENS_WIDTH / 2 + x] = offset; + offset = -iy * imgWidth + ix; + lens[LENS_WIDTH / 2 + y][LENS_WIDTH / 2 - x] = -offset; + lens[LENS_WIDTH / 2 - y][LENS_WIDTH / 2 + x] = offset; + } + } + } + + private void applyLens(int ox, int oy) { + for (int y = 0; y < LENS_WIDTH; y++) { + int temp = (y + oy) * imgWidth + ox; + for (int x = 0; x < LENS_WIDTH; x++) { + int pos = temp + x; + int backPos = pos + lens[y][x]; + imageData.setPixel(pos % imgWidth, pos / imgWidth, backing.getPixel(backPos % imgWidth, backPos / imgWidth)); + } + } + } +} diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/TEXFLAT2.png b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/TEXFLAT2.png new file mode 100644 index 0000000000..0934ec7ec0 Binary files /dev/null and b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/TEXFLAT2.png differ diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/bump.png b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/bump.png new file mode 100644 index 0000000000..312a7bac6e Binary files /dev/null and b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/bump.png differ diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/tuxblackbg.png b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/tuxblackbg.png new file mode 100644 index 0000000000..1d722c43b0 Binary files /dev/null and b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/graphics/tuxblackbg.png differ