2022-04-14 20:35:42 +00:00
|
|
|
|
2022-04-12 10:08:58 +00:00
|
|
|
/**
|
|
|
|
* A "virtual" screen, where only "setPixel" is available
|
|
|
|
* (It is a JFrame, and JFrame.EXIT_ON_CLOSE is set)
|
|
|
|
* @author smondet
|
|
|
|
*/
|
|
|
|
|
|
|
|
import java.awt.*;
|
|
|
|
import java.awt.geom.*;
|
|
|
|
import java.awt.image.*;
|
|
|
|
import javax.swing.*;
|
|
|
|
import java.lang.Math;
|
|
|
|
|
|
|
|
class ImageComponent extends Component {
|
|
|
|
|
|
|
|
BufferedImage renderedImage = null;
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
public ImageComponent(BufferedImage init) {
|
2022-04-12 10:08:58 +00:00
|
|
|
renderedImage = init;
|
|
|
|
}
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
public BufferedImage swapImage(BufferedImage bi) {
|
|
|
|
BufferedImage ret = renderedImage;
|
|
|
|
renderedImage = bi;
|
|
|
|
return ret;
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void paint(Graphics g) {
|
|
|
|
|
|
|
|
if (renderedImage != null) {
|
2022-04-14 20:35:42 +00:00
|
|
|
((Graphics2D) g).drawImage(renderedImage, new AffineTransform(1f, 0f, 0f, 1f, 0, 0), null);
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class GraphicsWrapper {
|
|
|
|
|
|
|
|
private int height = 0;
|
|
|
|
private int width = 0;
|
|
|
|
private int pixelSize = 0;
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
private JFrame myFrame;
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
private ImageComponent drawComp = null;
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
private BufferedImage backBuffer = null;
|
|
|
|
private BufferedImage frontBuffer = null;
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
private void init() {
|
2022-04-14 20:35:42 +00:00
|
|
|
backBuffer = new BufferedImage(width * pixelSize, height * pixelSize, BufferedImage.TYPE_INT_ARGB);
|
2022-04-12 10:08:58 +00:00
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
frontBuffer = new BufferedImage(width * pixelSize, height * pixelSize, BufferedImage.TYPE_3BYTE_BGR);
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
/*
|
2022-04-14 20:35:42 +00:00
|
|
|
* Graphics2D gd = initial.createGraphics ();
|
|
|
|
* gd.setColor (Color.BLACK) ;
|
|
|
|
* gd.fillRect (0,0, width * pixelSize, height * pixelSize) ;
|
|
|
|
* gd = drawingImage.createGraphics ();
|
|
|
|
* gd.setColor (Color.BLACK) ;
|
|
|
|
* gd.fillRect (0,0, width * pixelSize, height * pixelSize) ;
|
|
|
|
*/
|
|
|
|
|
|
|
|
drawComp = new ImageComponent(frontBuffer);
|
|
|
|
drawComp.setPreferredSize(new Dimension(width * pixelSize, height * pixelSize));
|
|
|
|
drawComp.setVisible(true);
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
myFrame = new JFrame("Simple Inverse Rasterization Renderer (TSI)");
|
2022-04-14 20:35:42 +00:00
|
|
|
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
myFrame.add("Center", drawComp);
|
2022-04-12 10:08:58 +00:00
|
|
|
myFrame.pack();
|
|
|
|
myFrame.setVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a virtual screen of size width x height
|
|
|
|
* And set its window visible.
|
|
|
|
*/
|
|
|
|
public GraphicsWrapper(int width, int height) {
|
|
|
|
this.height = height;
|
|
|
|
this.width = width;
|
|
|
|
this.pixelSize = 1;
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-04-14 20:35:42 +00:00
|
|
|
* Build a virtual screen of size width x height, where one virtual pixel is
|
|
|
|
* represented by
|
2022-04-12 10:08:58 +00:00
|
|
|
* a pixelSize x pixelSize square.
|
|
|
|
* And set its window visible.
|
|
|
|
*/
|
|
|
|
public GraphicsWrapper(int width, int height, int pixelSize) {
|
|
|
|
this.height = height;
|
|
|
|
this.width = width;
|
2022-04-14 20:35:42 +00:00
|
|
|
this.pixelSize = pixelSize;
|
2022-04-12 10:08:58 +00:00
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lights the pixel (x,y) with color (r, g, b) (values clamped to [0,1])
|
|
|
|
* on the current draw buffer.
|
|
|
|
* Does nothing for pixels out of the screen.
|
|
|
|
*/
|
2022-04-14 20:35:42 +00:00
|
|
|
public void setPixel(int x, int y, double r, double g, double b) {
|
|
|
|
|
|
|
|
r = Math.min(1.0, Math.max(0.0, r));
|
|
|
|
g = Math.min(1.0, Math.max(0.0, g));
|
|
|
|
b = Math.min(1.0, Math.max(0.0, b));
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
setPixel(x, y, (char) (r * 255), (char) (g * 255), (char) (b * 255));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lights the pixel (x,y) with color (r, g, b) (values clamped to [0, 255])
|
2022-04-14 20:35:42 +00:00
|
|
|
* on the current draw buffer.
|
2022-04-12 10:08:58 +00:00
|
|
|
* Does nothing for pixels out of the screen.
|
|
|
|
*/
|
2022-04-14 20:35:42 +00:00
|
|
|
public void setPixel(int x, int y, char r, char g, char b) {
|
|
|
|
|
|
|
|
if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
|
|
|
|
int argb = 0xFF000000;
|
|
|
|
argb += ((int) r) << (8 * 2);
|
|
|
|
argb += ((int) g) << (8 * 1);
|
|
|
|
argb += ((int) b);
|
|
|
|
|
|
|
|
for (int i = 0; i < pixelSize; i++) {
|
|
|
|
for (int j = 0; j < pixelSize; j++) {
|
|
|
|
frontBuffer.setRGB(i + (x * pixelSize), j + (y * pixelSize), argb);
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
2022-04-14 20:35:42 +00:00
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
2022-04-14 20:35:42 +00:00
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Lights the pixel (x,y) with the given color.
|
|
|
|
* Does nothing for pixels out of the screen.
|
|
|
|
*/
|
2022-04-14 20:35:42 +00:00
|
|
|
public void setPixel(int x, int y, Color color) {
|
|
|
|
|
|
|
|
if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
|
|
|
|
int rgb = color.getRGB();
|
|
|
|
for (int i = 0; i < pixelSize; i++) {
|
|
|
|
for (int j = 0; j < pixelSize; j++) {
|
|
|
|
frontBuffer.setRGB(i + (x * pixelSize), j + (y * pixelSize), rgb);
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
2022-04-14 20:35:42 +00:00
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
2022-04-14 20:35:42 +00:00
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the pixel in the back buffer
|
2022-04-14 20:35:42 +00:00
|
|
|
*/
|
|
|
|
public Color getPixel(int x, int y) {
|
|
|
|
Color color;
|
2022-04-12 10:08:58 +00:00
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
|
|
|
|
color = new Color(frontBuffer.getRGB(x, y), false);
|
|
|
|
} else {
|
|
|
|
color = Color.BLACK;
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
return color;
|
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
public Color getFrontPixel(int x, int y) {
|
|
|
|
Color color;
|
2022-04-12 10:08:58 +00:00
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
|
|
|
|
color = new Color(frontBuffer.getRGB(x, y), false);
|
|
|
|
} else {
|
|
|
|
color = Color.BLACK;
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 20:35:42 +00:00
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int getWidth() {
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getHeight() {
|
|
|
|
return height;
|
|
|
|
}
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear current draw-buffer (ie Paint it black)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public void clearBuffer() {
|
2022-04-14 20:35:42 +00:00
|
|
|
Graphics2D gd = frontBuffer.createGraphics();
|
|
|
|
gd.setColor(Color.BLACK);
|
|
|
|
gd.fillRect(0, 0, width * pixelSize, height * pixelSize);
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw current draw-buffer on the window.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public void swapBuffers() {
|
2022-04-14 20:35:42 +00:00
|
|
|
frontBuffer = drawComp.swapImage(frontBuffer);
|
|
|
|
myFrame.repaint();
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy window.
|
|
|
|
*/
|
|
|
|
public void destroy() {
|
|
|
|
myFrame.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|