2022-11-28 10:29:34 -06:00
|
|
|
package sig.engine;
|
|
|
|
import java.awt.Graphics;
|
|
|
|
import java.awt.Image;
|
|
|
|
import java.awt.Toolkit;
|
|
|
|
import java.awt.image.ColorModel;
|
|
|
|
import java.awt.image.MemoryImageSource;
|
|
|
|
import java.util.ArrayList;
|
2022-11-28 11:48:13 -06:00
|
|
|
import java.util.HashMap;
|
2022-11-28 10:29:34 -06:00
|
|
|
import java.util.List;
|
2022-11-28 11:48:13 -06:00
|
|
|
import java.awt.event.KeyEvent;
|
|
|
|
import java.awt.event.MouseEvent;
|
|
|
|
import java.awt.event.MouseMotionListener;
|
|
|
|
import java.awt.event.MouseWheelEvent;
|
|
|
|
import java.awt.event.MouseWheelListener;
|
|
|
|
|
|
|
|
import java.awt.GraphicsEnvironment;
|
|
|
|
import java.awt.GraphicsConfiguration;
|
|
|
|
|
2022-11-28 10:29:34 -06:00
|
|
|
|
|
|
|
import javax.swing.JFrame;
|
|
|
|
import javax.swing.JPanel;
|
2022-11-28 11:48:13 -06:00
|
|
|
import javax.swing.event.MouseInputListener;
|
|
|
|
|
|
|
|
import java.awt.event.KeyListener;
|
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.RenderingHints;
|
2022-11-28 10:29:34 -06:00
|
|
|
|
|
|
|
import sig.JavaProjectTemplate;
|
|
|
|
|
2022-11-28 11:48:13 -06:00
|
|
|
public class Panel extends JPanel implements Runnable,KeyListener {
|
2022-11-28 10:29:34 -06:00
|
|
|
JFrame window;
|
2022-11-28 13:03:32 -06:00
|
|
|
static JavaProjectTemplate gameInstance;
|
2022-11-28 10:29:34 -06:00
|
|
|
public int pixel[];
|
|
|
|
final int CIRCLE_PRECISION=32;
|
|
|
|
final int OUTLINE_COL=Color.BRIGHT_WHITE.getColor();
|
|
|
|
private Thread thread;
|
|
|
|
private Image imageBuffer;
|
|
|
|
private MemoryImageSource mImageProducer;
|
|
|
|
private ColorModel cm;
|
|
|
|
int scanLine=0;
|
|
|
|
int nextScanLine=0;
|
|
|
|
double x_offset=0;
|
|
|
|
double y_offset=0;
|
|
|
|
int frameCount=0;
|
|
|
|
long lastSecond=0;
|
2022-11-28 11:48:13 -06:00
|
|
|
boolean resizing=false;
|
|
|
|
long lastUpdate=System.nanoTime();
|
|
|
|
final long TARGET_FRAMETIME = 8333333l;
|
|
|
|
public double nanaX = 0;
|
|
|
|
public double nanaY = 0;
|
|
|
|
public int button = 0;
|
|
|
|
public HashMap<Integer,Boolean> MOUSE = new HashMap<>();
|
2022-11-28 13:36:26 -06:00
|
|
|
private Point<Integer> mousePosition = new Point<Integer>(0,0);
|
2022-11-28 11:48:13 -06:00
|
|
|
private MouseScrollValue scrollWheel=null;
|
2022-11-28 12:17:28 -06:00
|
|
|
public static final int UPDATE_LOOP_FRAMERATE = 244;
|
|
|
|
public static final long UPDATE_LOOP_NANOTIME = (long)((1d/UPDATE_LOOP_FRAMERATE)*1000000000l);
|
|
|
|
public static final double UPDATE_MULT = 1d / UPDATE_LOOP_FRAMERATE;
|
2022-11-28 11:48:13 -06:00
|
|
|
|
|
|
|
public static RenderingHints RENDERHINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
|
|
|
|
|
|
|
|
static long lastReportedTime = System.currentTimeMillis();
|
|
|
|
public static long TIME = 0;
|
|
|
|
public static long scaleTime;
|
|
|
|
public static Panel p;
|
|
|
|
public static JFrame f;
|
|
|
|
|
2022-11-28 13:03:32 -06:00
|
|
|
public static void InitializeEngine(JavaProjectTemplate instance){
|
2022-11-28 11:48:13 -06:00
|
|
|
System.setProperty("sun.java2d.transaccel", "True");
|
|
|
|
System.setProperty("sun.java2d.d3d", "True");
|
|
|
|
System.setProperty("sun.java2d.ddforcevram", "True");
|
|
|
|
System.setProperty("sun.java2d.xrender", "True");
|
|
|
|
|
2022-11-28 13:03:32 -06:00
|
|
|
gameInstance=instance;
|
|
|
|
|
2022-11-28 11:48:13 -06:00
|
|
|
RENDERHINTS.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
|
|
|
RENDERHINTS.put(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_DISABLE);
|
|
|
|
RENDERHINTS.put(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
|
|
|
|
RENDERHINTS.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_SPEED);
|
|
|
|
|
|
|
|
f = new JFrame(JavaProjectTemplate.PROGRAM_NAME);
|
|
|
|
f.setResizable(false);
|
|
|
|
f.setSize(JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT);
|
|
|
|
p = new Panel(f);
|
|
|
|
JavaProjectTemplate.game=p;
|
|
|
|
|
|
|
|
p.init();
|
|
|
|
|
|
|
|
f.add(p);
|
|
|
|
f.addKeyListener(p);
|
|
|
|
f.setLocation((int) ((Toolkit.getDefaultToolkit().getScreenSize().getWidth() - f.getWidth()) / 2),
|
|
|
|
(int) ((Toolkit.getDefaultToolkit().getScreenSize().getHeight() - f.getHeight()) / 2));
|
|
|
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
f.setVisible(true);
|
|
|
|
|
|
|
|
p.render();
|
2022-11-28 12:17:28 -06:00
|
|
|
|
|
|
|
long lastGameTime = System.nanoTime();
|
|
|
|
long dt = 0;
|
|
|
|
while (true) {
|
|
|
|
dt += System.nanoTime() - lastGameTime;
|
|
|
|
lastGameTime = System.nanoTime();
|
|
|
|
while (dt >= UPDATE_LOOP_NANOTIME) {
|
2022-11-28 13:03:32 -06:00
|
|
|
gameInstance.updateGame(UPDATE_LOOP_NANOTIME/1000000000d);
|
2022-11-28 12:17:28 -06:00
|
|
|
dt -= UPDATE_LOOP_NANOTIME;
|
|
|
|
TIME += UPDATE_LOOP_NANOTIME;
|
|
|
|
}
|
|
|
|
gameUpdateLoopStabilizer(dt); //This is hackish. Removing this slows down the game by about 30%. The timer runs slower. ???
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void gameUpdateLoopStabilizer(long dt) {
|
|
|
|
if (dt < UPDATE_LOOP_NANOTIME) {
|
|
|
|
lastReportedTime = System.currentTimeMillis();
|
|
|
|
} else {
|
|
|
|
if (System.currentTimeMillis() - lastReportedTime > 5000) {
|
|
|
|
System.out.println("WARNING! Game is lagging behind! Frames Behind: " + (dt / UPDATE_LOOP_NANOTIME));
|
|
|
|
lastReportedTime = System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
Thread.sleep(4);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
2022-11-28 10:29:34 -06:00
|
|
|
|
|
|
|
public Panel(JFrame f) {
|
|
|
|
super(true);
|
|
|
|
this.window=f;
|
|
|
|
thread = new Thread(this, "MyPanel Thread");
|
2022-11-28 11:48:13 -06:00
|
|
|
|
|
|
|
this.addMouseListener(new MouseInputListener(){
|
|
|
|
@Override
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mousePressed(MouseEvent e) {
|
|
|
|
MOUSE.put(e.getButton(),true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseReleased(MouseEvent e) {
|
|
|
|
MOUSE.put(e.getButton(),false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseEntered(MouseEvent e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseExited(MouseEvent e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseDragged(MouseEvent e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseMoved(MouseEvent e) {
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.addMouseMotionListener(new MouseMotionListener(){
|
|
|
|
@Override
|
|
|
|
public void mouseDragged(MouseEvent e) {
|
|
|
|
mousePosition.set(e.getX(),e.getY());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void mouseMoved(MouseEvent e) {
|
|
|
|
mousePosition.set(e.getX(),e.getY());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.addMouseWheelListener(new MouseWheelListener(){
|
|
|
|
//-1 is UP, 1 is DOWN
|
|
|
|
@Override
|
|
|
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
|
|
scrollWheel=MouseScrollValue.getValue(e.getWheelRotation());
|
|
|
|
}
|
|
|
|
});
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
2022-11-28 11:48:13 -06:00
|
|
|
/**
|
2022-11-28 10:29:34 -06:00
|
|
|
* Get Best Color model available for current screen.
|
|
|
|
* @return color model
|
|
|
|
*/
|
|
|
|
protected static ColorModel getCompatibleColorModel(){
|
|
|
|
GraphicsConfiguration gfx_config = GraphicsEnvironment.
|
|
|
|
getLocalGraphicsEnvironment().getDefaultScreenDevice().
|
|
|
|
getDefaultConfiguration();
|
|
|
|
return gfx_config.getColorModel();
|
|
|
|
}
|
|
|
|
|
2022-11-28 11:48:13 -06:00
|
|
|
|
2022-11-28 10:29:34 -06:00
|
|
|
/**
|
|
|
|
* Call it after been visible and after resizes.
|
|
|
|
*/
|
|
|
|
public void init(){
|
|
|
|
cm = getCompatibleColorModel();
|
2022-11-28 11:48:13 -06:00
|
|
|
int screenSize = JavaProjectTemplate.WINDOW_WIDTH * JavaProjectTemplate.WINDOW_HEIGHT;
|
2022-11-28 10:29:34 -06:00
|
|
|
if(pixel == null || pixel.length < screenSize){
|
|
|
|
pixel = new int[screenSize];
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
mImageProducer = new MemoryImageSource(JavaProjectTemplate.WINDOW_WIDTH, JavaProjectTemplate.WINDOW_HEIGHT, cm, pixel,0, JavaProjectTemplate.WINDOW_WIDTH);
|
2022-11-28 10:29:34 -06:00
|
|
|
mImageProducer.setAnimated(true);
|
|
|
|
mImageProducer.setFullBufferUpdates(true);
|
2022-11-28 11:48:13 -06:00
|
|
|
imageBuffer = Toolkit.getDefaultToolkit().createImage(mImageProducer);
|
|
|
|
if(thread.isInterrupted() || !thread.isAlive()){
|
|
|
|
thread.start();
|
|
|
|
}
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void paintComponent(Graphics g) {
|
2022-11-28 11:48:13 -06:00
|
|
|
//super.paintComponent(g);
|
|
|
|
// perform draws on pixels
|
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
g.drawImage(this.imageBuffer,0,0,JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT,0,0,JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT,this);
|
|
|
|
scaleTime=System.currentTimeMillis()-startTime;
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overrides ImageObserver.imageUpdate.
|
|
|
|
* Always return true, assuming that imageBuffer is ready to go when called
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public boolean imageUpdate(Image image, int a, int b, int c, int d, int e) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Do your draws in here !!
|
|
|
|
* pixel is your canvas!
|
|
|
|
*/
|
2022-11-28 11:48:13 -06:00
|
|
|
|
|
|
|
|
2022-11-28 10:29:34 -06:00
|
|
|
public /* abstract */ void render(){
|
2022-11-28 13:03:32 -06:00
|
|
|
gameInstance.drawGame();
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
2022-11-28 13:27:45 -06:00
|
|
|
public void FillCircle(double center_x,double center_y,double r,Color col) {
|
2022-11-28 10:29:34 -06:00
|
|
|
int counter=0;
|
2022-11-28 13:36:26 -06:00
|
|
|
List<Point<Integer>> points = new ArrayList<Point<Integer>>();
|
2022-11-28 10:29:34 -06:00
|
|
|
for (double theta=0;theta<Math.PI*2;theta+=((Math.PI*2)/CIRCLE_PRECISION)) {
|
|
|
|
//System.out.println("Loop "+counter+++". Theta:"+theta);
|
|
|
|
//System.out.println("X:"+(Math.sin(theta)*r+center_x)+" Y:"+(Math.cos(theta)*r+center_y));
|
2022-11-28 13:36:26 -06:00
|
|
|
points.add(new Point<Integer>((int)(Math.round(Math.sin(theta)*r+center_x)),(int)(Math.round(Math.cos(theta)*r+center_y))));
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
2022-11-28 13:27:45 -06:00
|
|
|
FillPolygon(0,0,col,points);
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-11-28 13:27:45 -06:00
|
|
|
public void FillOval(double center_x,double center_y,double w,double h,Color col) {
|
2022-11-28 10:29:34 -06:00
|
|
|
int counter=0;
|
2022-11-28 13:36:26 -06:00
|
|
|
List<Point<Integer>> points = new ArrayList<Point<Integer>>();
|
2022-11-28 10:29:34 -06:00
|
|
|
double r = Math.max(w,h);
|
|
|
|
double ratio = Math.min(w,h)/r;
|
|
|
|
for (double theta=0;theta<Math.PI*2;theta+=((Math.PI*2)/CIRCLE_PRECISION)) {
|
|
|
|
//System.out.println("Loop "+counter+++". Theta:"+theta);
|
|
|
|
//System.out.println("X:"+(Math.sin(theta)*r+center_x)+" Y:"+(Math.cos(theta)*r+center_y));
|
2022-11-28 13:36:26 -06:00
|
|
|
Point<Integer> newP = new Point<Integer>((int)(Math.round(Math.sin(theta)*r)),(int)(Math.round(Math.cos(theta)*r)));
|
2022-11-28 10:29:34 -06:00
|
|
|
if (w<h) {
|
|
|
|
newP.x=(int)Math.round(newP.x*ratio);
|
|
|
|
} else {
|
|
|
|
newP.y=(int)Math.round(newP.y*ratio);
|
|
|
|
}
|
2022-11-28 13:36:26 -06:00
|
|
|
newP.x+=(int)center_x;
|
|
|
|
newP.y+=(int)center_y;
|
|
|
|
points.add(newP);
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
2022-11-28 13:27:45 -06:00
|
|
|
FillPolygon(0,0,col,points);
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
2022-11-28 13:36:26 -06:00
|
|
|
public void FillPolygon(double x_offset,double y_offset,Color col,List<Point<Integer>>points) {
|
|
|
|
Edge[] edges = new Edge[points.size()];
|
2022-11-28 10:29:34 -06:00
|
|
|
List<Edge> edges_sorted = new ArrayList<Edge>();
|
2022-11-28 13:36:26 -06:00
|
|
|
for (int i=0;i<points.size();i++) {
|
|
|
|
edges[i] = new Edge(points.get(i),points.get((i+1)%points.size()));
|
2022-11-28 10:29:34 -06:00
|
|
|
if (!Double.isInfinite(edges[i].inverse_slope)) {
|
|
|
|
if (edges_sorted.size()==0) {
|
|
|
|
edges_sorted.add(edges[i]);
|
|
|
|
} else {
|
|
|
|
boolean inserted=false;
|
|
|
|
for (int j=0;j<edges_sorted.size();j++) {
|
|
|
|
Edge e2 = edges_sorted.get(j);
|
|
|
|
if (e2.min_y>=edges[i].min_y) {
|
|
|
|
edges_sorted.add(j,edges[i]);
|
|
|
|
inserted=true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!inserted) {
|
|
|
|
edges_sorted.add(edges[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//System.out.println(edges_sorted);
|
|
|
|
List<Edge> active_edges = new ArrayList<Edge>();
|
|
|
|
scanLine = edges_sorted.get(0).min_y-1;
|
|
|
|
nextScanLine = scanLine+1;
|
|
|
|
do {
|
|
|
|
for (int i=0;i<active_edges.size();i+=2) {
|
2022-11-28 13:03:32 -06:00
|
|
|
if (i>=active_edges.size()-1) break;
|
2022-11-28 10:29:34 -06:00
|
|
|
Edge e1 = active_edges.get(i);
|
|
|
|
Edge e2 = active_edges.get(i+1);
|
|
|
|
//System.out.println("Drawing from "+((int)Math.round(e1.x_of_min_y))+" to "+e2.x_of_min_y+" on line "+scanLine);
|
|
|
|
for (int x=(int)Math.round(e1.x_of_min_y);x<=e2.x_of_min_y;x++) {
|
2022-11-28 13:03:32 -06:00
|
|
|
if (x<0||x>JavaProjectTemplate.WINDOW_WIDTH) continue;
|
2022-11-28 11:48:13 -06:00
|
|
|
int index = (scanLine+(int)y_offset)*getWidth()+x+(int)x_offset;
|
2022-11-28 12:17:28 -06:00
|
|
|
if (index<pixel.length&&index>=0) {
|
|
|
|
Draw(index,col.getColor());
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
List<Edge> new_active_edges = new ArrayList<Edge>();
|
|
|
|
for (int i=0;i<active_edges.size();i++) {
|
|
|
|
Edge e = active_edges.get(i);
|
|
|
|
if (e.max_y==scanLine+1) {
|
|
|
|
active_edges.remove(i--);
|
|
|
|
} else {
|
|
|
|
e.x_of_min_y+=e.inverse_slope;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
scanLine++;
|
|
|
|
for (int i=0;i<active_edges.size();i++) {
|
|
|
|
Edge e = active_edges.get(i);
|
|
|
|
boolean inserted=false;
|
|
|
|
for (int j=0;j<new_active_edges.size();j++) {
|
|
|
|
Edge e2 = new_active_edges.get(j);
|
|
|
|
if (e2.x_of_min_y>e.x_of_min_y) {
|
|
|
|
new_active_edges.add(j,e);
|
|
|
|
inserted=true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!inserted) {
|
|
|
|
new_active_edges.add(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
active_edges=new_active_edges;
|
|
|
|
GetNextScanLineEdges(edges_sorted, active_edges);
|
|
|
|
}
|
|
|
|
while (active_edges.size()>0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void GetNextScanLineEdges(List<Edge> edges_sorted, List<Edge> active_edges) {
|
|
|
|
if (scanLine==nextScanLine) {
|
|
|
|
for (int i=0;i<edges_sorted.size();i++) {
|
|
|
|
Edge e = edges_sorted.get(i);
|
|
|
|
if (e.min_y==scanLine) {
|
|
|
|
e = edges_sorted.remove(i--);
|
|
|
|
boolean inserted=false;
|
|
|
|
for (int j=0;j<active_edges.size();j++) {
|
|
|
|
if (e.x_of_min_y<active_edges.get(j).x_of_min_y) {
|
|
|
|
active_edges.add(j,e);
|
|
|
|
inserted=true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!inserted) {
|
|
|
|
active_edges.add(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
if (e.min_y>scanLine) {
|
|
|
|
nextScanLine=e.min_y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-28 12:17:28 -06:00
|
|
|
public void Draw(int x, int y, Color col) {
|
|
|
|
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Draw(int index, int col) {
|
2022-11-28 11:48:13 -06:00
|
|
|
pixel[index]=col;
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
while (true) {
|
|
|
|
// request a JPanel re-drawing
|
2022-11-28 11:48:13 -06:00
|
|
|
render();
|
|
|
|
mImageProducer.newPixels();
|
2022-11-28 12:17:28 -06:00
|
|
|
if (f!=null) {
|
|
|
|
Graphics2D g2 = (Graphics2D)f.getGraphics();
|
|
|
|
if (g2!=null) {
|
|
|
|
g2.setRenderingHints(RENDERHINTS);
|
|
|
|
try {
|
|
|
|
repaint();
|
|
|
|
} finally {
|
|
|
|
g2.dispose();
|
|
|
|
}
|
|
|
|
}
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
updateFPSCounter();
|
2022-11-28 10:29:34 -06:00
|
|
|
//System.out.println("Repaint "+frameCount++);
|
2022-11-28 11:48:13 -06:00
|
|
|
waitForNextFrame();
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|
|
|
|
}
|
2022-11-28 11:48:13 -06:00
|
|
|
|
|
|
|
private void waitForNextFrame() {
|
|
|
|
long newTime = System.nanoTime();
|
|
|
|
if (newTime-lastUpdate<TARGET_FRAMETIME) {
|
|
|
|
long timeRemaining=TARGET_FRAMETIME-(newTime-lastUpdate);
|
|
|
|
long millis = timeRemaining/1000000l;
|
|
|
|
int nanos = (int)(timeRemaining-millis*1000000l);
|
|
|
|
//System.out.println(timeRemaining+"/"+millis+" Nanos:"+nanos);
|
|
|
|
try {
|
|
|
|
Thread.sleep(millis,nanos);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lastUpdate=newTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateFPSCounter() {
|
|
|
|
if (window!=null&&System.currentTimeMillis()-lastSecond>=1000) {
|
|
|
|
window.setTitle(JavaProjectTemplate.PROGRAM_NAME+" - FPS: "+(frameCount));
|
|
|
|
frameCount=0;
|
|
|
|
lastSecond=System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
frameCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void keyTyped(KeyEvent e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void keyPressed(KeyEvent e) {
|
|
|
|
if (!Key.isKeyHeld(e.getKeyCode())) {
|
|
|
|
Key.setKeyHeld(e.getKeyCode(), true);
|
|
|
|
}
|
|
|
|
//System.out.println("Key List: "+KEYS);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void keyReleased(KeyEvent e) {
|
|
|
|
Key.setKeyHeld(e.getKeyCode(), false);
|
|
|
|
//System.out.println("Key List: "+KEYS);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Text(double x, double y, String s, Font f) {
|
|
|
|
Draw_Text_Ext(x,y,s,f,Color.BLACK);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Text_Ext(double x, double y, String s, Font f, Color col) {
|
|
|
|
java.lang.String finalS = s.toString();
|
|
|
|
int charCount=0;
|
|
|
|
int yOffset=0;
|
|
|
|
int xOffset=0;
|
|
|
|
Color currentCol = col;
|
|
|
|
for (int i=0;i<finalS.length();i++) {
|
|
|
|
if (finalS.charAt(i)=='\n') {
|
|
|
|
xOffset+=(charCount+1)*f.getGlyphWidth();
|
|
|
|
yOffset+=f.getGlyphHeight();
|
|
|
|
charCount=0;
|
|
|
|
} else {
|
|
|
|
Draw_Sprite_Partial_Ext(x+i*f.getGlyphWidth()-xOffset, y+yOffset, f.getCharInfo(finalS.charAt(i)).getX(), f.getCharInfo(finalS.charAt(i)).getY(), f.getCharInfo(finalS.charAt(i)).getWidth(), f.getCharInfo(finalS.charAt(i)).getHeight(), f.getSprite(), 0,currentCol,Transform.NONE);
|
|
|
|
charCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-28 12:17:28 -06:00
|
|
|
public void Draw_Line(int x1,int y1,int x2,int y2,Color col) {
|
2022-11-28 11:48:13 -06:00
|
|
|
int x,y,dx,dy,dx1,dy1,px,py,xe,ye;
|
|
|
|
dx=x2-x1;dy=y2-y1;
|
|
|
|
dx1=Math.abs(dx);dy1=Math.abs(dy);
|
|
|
|
px=2*dy1-dx1;py=2*dx1-dy1;
|
|
|
|
if (dy1<=dx1) {
|
|
|
|
if (dx>=0) {
|
|
|
|
x=x1;y=y1;xe=x2-1;
|
|
|
|
} else {
|
|
|
|
x=x2-1;y=y2-1;xe=x1;
|
|
|
|
}
|
|
|
|
while (x<xe) {
|
|
|
|
x=x+1;
|
|
|
|
if (px<0) {
|
|
|
|
px=px+2*dy1;
|
|
|
|
} else {
|
|
|
|
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
|
|
|
|
y=y+1;
|
|
|
|
} else {
|
|
|
|
y=y-1;
|
|
|
|
}
|
|
|
|
px=px+2*(dy1-dx1);
|
|
|
|
}
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (dy>=0) {
|
|
|
|
x=x1;y=y1;ye=y2-1;
|
|
|
|
} else {
|
|
|
|
x=x2-1;y=y2-1;ye=y1;
|
|
|
|
}
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
while (y<ye) {
|
|
|
|
y=y+1;
|
|
|
|
if (py<=0) {
|
|
|
|
py=py+2*dx1;
|
|
|
|
} else {
|
|
|
|
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
|
|
|
|
x=x+1;
|
|
|
|
} else {
|
|
|
|
x=x-1;
|
|
|
|
}
|
|
|
|
py=py+2*(dx1-dy1);
|
|
|
|
}
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-28 13:27:45 -06:00
|
|
|
public void Fill_Rect(double x,double y,double w,double h,Color col) {
|
2022-11-28 11:48:13 -06:00
|
|
|
for (int xx=0;xx<w;xx++) {
|
|
|
|
for (int yy=0;yy<h;yy++) {
|
|
|
|
if (x+xx>=0&&y+yy>=0&&x+xx<JavaProjectTemplate.WINDOW_WIDTH&&y+yy<JavaProjectTemplate.WINDOW_HEIGHT) {
|
|
|
|
int index = ((int)y+yy)*JavaProjectTemplate.WINDOW_WIDTH+(int)x+xx;
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(index,col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Sprite(double x, double y, Sprite sprite){
|
|
|
|
Draw_Sprite_Partial(x,y,0,0,sprite.getWidth(),sprite.getHeight(),sprite,0,Transform.NONE );
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Animated_Sprite(double x, double y, AnimatedSprite sprite, double frameIndex){
|
|
|
|
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
|
|
|
|
Draw_Sprite_Partial(x,y,frameRectangle.getX(),frameRectangle.getY(),frameRectangle.getWidth(),frameRectangle.getHeight(),sprite,frameIndex,Transform.NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Sprite(double x, double y, Sprite sprite, Transform transform){
|
|
|
|
Draw_Sprite_Partial(x,y,0,0,sprite.getWidth(),sprite.getHeight(),sprite,0,transform);
|
|
|
|
}
|
|
|
|
public void Draw_Animated_Sprite(double x, double y, AnimatedSprite sprite, double frameIndex, Transform transform){
|
|
|
|
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
|
|
|
|
Draw_Sprite_Partial(x,y,frameRectangle.getX(),frameRectangle.getY(),frameRectangle.getWidth(),frameRectangle.getHeight(),sprite,frameIndex, transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Sprite_Partial(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, double frame_index, Transform transform){
|
|
|
|
Draw_Sprite_Partial_Ext(x,y,xOffset,yOffset,w,h,sprite,frame_index, Color.WHITE,transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, Transform transform){
|
|
|
|
Draw_Sprite_Partial_Ext(x, y, xOffset, yOffset, w, h, sprite, 0, Color.WHITE, transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Animated_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, AnimatedSprite sprite, double frameIndex, Transform transform){
|
|
|
|
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
|
|
|
|
Draw_Sprite_Partial_Ext(x, y, frameRectangle.getX(), frameRectangle.getY(), frameRectangle.getWidth(), frameRectangle.getHeight(), sprite, 0, Color.WHITE, transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, double frame_index, Color col, Transform transform){
|
|
|
|
boolean horizontal = transform==Transform.HORIZONTAL||transform==Transform.HORIZ_VERTIC;
|
|
|
|
boolean vertical = transform==Transform.VERTICAL||transform==Transform.HORIZ_VERTIC;
|
|
|
|
for(int X=(int)xOffset;X<(int)(w+xOffset);X++){
|
|
|
|
for(int Y=(int)yOffset;Y<(int)(h+yOffset);Y++){
|
|
|
|
if (X+x-xOffset<0||Y+y-yOffset<0||X-xOffset+x>=JavaProjectTemplate.WINDOW_WIDTH||Y-yOffset+y>=JavaProjectTemplate.WINDOW_HEIGHT) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
int index =
|
|
|
|
((vertical?
|
|
|
|
sprite.getHeight()-(Y-(int)yOffset):
|
|
|
|
(Y-(int)yOffset))
|
|
|
|
+(int)y)*JavaProjectTemplate.WINDOW_WIDTH+
|
|
|
|
(horizontal?
|
|
|
|
sprite.getWidth()-(X-(int)xOffset):
|
|
|
|
(X-(int)xOffset))
|
|
|
|
+(int)x;
|
|
|
|
if (((sprite.getImg().getRGB(X,Y)>>>24)&0xFF)==0||index<0||index>=pixel.length) {
|
|
|
|
continue;
|
|
|
|
} else {
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(index,(col==Color.WHITE)?sprite.getImg().getRGB(X,Y):col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-28 13:27:45 -06:00
|
|
|
public void Draw_Rect(double x,double y, double w, double h, Color col) {
|
|
|
|
Draw_Line((int)x, (int)y, (int)x+(int)w, (int)y, col);
|
|
|
|
Draw_Line((int)x+(int)w, (int)y, (int)x+(int)w, (int)y+(int)h, col);
|
|
|
|
Draw_Line((int)x+(int)w, (int)y+(int)h, (int)x, (int)y+(int)h, col);
|
|
|
|
Draw_Line((int)x, (int)y+(int)h, (int)x, (int)y, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw_Triangle(double x1, double y1, double x2, double y2, double x3, double y3, Color col) {
|
|
|
|
Draw_Line((int)x1, (int)y1, (int)x2, (int)y2, col);
|
|
|
|
Draw_Line((int)x2, (int)y2, (int)x3, (int)y3, col);
|
|
|
|
Draw_Line((int)x3, (int)y3, (int)x1, (int)y1, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void drawline(int sx,int ex,int ny,Color col){
|
|
|
|
for (int i = sx; i <= ex; i++) Draw(i, ny, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Fill_Triangle(double x1, double y1, double x2, double y2, double x3, double y3, Color col){
|
|
|
|
int t1x, t2x, y, minx, maxx, t1xp, t2xp;
|
|
|
|
boolean changed1 = false;
|
|
|
|
boolean changed2 = false;
|
|
|
|
int signx1, signx2, dx1, dy1, dx2, dy2;
|
|
|
|
int e1, e2;
|
|
|
|
// Sort vertices
|
|
|
|
int temp;
|
|
|
|
if (y1 > y2) {temp=(int)y1;y1=y2;y2=temp;temp=(int)x1;x1=x2;x2=temp;}
|
|
|
|
if (y1 > y3) {temp=(int)y1;y1=y3;y3=temp;temp=(int)x1;x1=x3;x3=temp;}
|
|
|
|
if (y2 > y3) {temp=(int)y2;y2=y3;y3=temp;temp=(int)x2;x2=x3;x3=temp;}
|
|
|
|
|
|
|
|
t1x = t2x = (int)x1; y = (int)y1; // Starting points
|
|
|
|
dx1 = (int)(x2 - x1);
|
|
|
|
if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
|
|
|
|
else signx1 = 1;
|
|
|
|
dy1 = (int)(y2 - y1);
|
|
|
|
|
|
|
|
dx2 = (int)(x3 - x1);
|
|
|
|
if (dx2 < 0) { dx2 = -dx2; signx2 = -1; }
|
|
|
|
else signx2 = 1;
|
|
|
|
dy2 = (int)(y3 - y1);
|
|
|
|
|
|
|
|
if (dy1 > dx1) {temp=dx1;dx1=dy1;dy1=temp;changed1 = true; }
|
|
|
|
if (dy2 > dx2) {temp=dx2;dx2=dy2;dy2=temp;changed2 = true; }
|
|
|
|
|
|
|
|
e2 = (int)(dx2 >> 1);
|
|
|
|
// Flat top, just process the second half
|
|
|
|
boolean firstHalfDone=false;
|
|
|
|
if (y1 == y2) firstHalfDone=true;
|
|
|
|
if (!firstHalfDone) {
|
|
|
|
e1 = (int)(dx1 >> 1);
|
|
|
|
|
|
|
|
for (int i = 0; i < dx1;) {
|
|
|
|
t1xp = 0; t2xp = 0;
|
|
|
|
if (t1x < t2x) { minx = t1x; maxx = t2x; }
|
|
|
|
else { minx = t2x; maxx = t1x; }
|
|
|
|
// process first line until y value is about to change
|
|
|
|
next0:
|
|
|
|
while (i < dx1) {
|
|
|
|
i++;
|
|
|
|
e1 += dy1;
|
|
|
|
while (e1 >= dx1) {
|
|
|
|
e1 -= dx1;
|
|
|
|
if (changed1) t1xp = signx1;//t1x += signx1;
|
|
|
|
else {
|
|
|
|
break next0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (changed1) break;
|
|
|
|
else t1x += signx1;
|
|
|
|
}
|
|
|
|
// Move line
|
|
|
|
next1:
|
|
|
|
// process second line until y value is about to change
|
|
|
|
while (true) {
|
|
|
|
e2 += dy2;
|
|
|
|
while (e2 >= dx2) {
|
|
|
|
e2 -= dx2;
|
|
|
|
if (changed2) t2xp = signx2;//t2x += signx2;
|
|
|
|
else {
|
|
|
|
break next1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (changed2) break;
|
|
|
|
else t2x += signx2;
|
|
|
|
}
|
|
|
|
if (minx > t1x) minx = t1x;
|
|
|
|
if (minx > t2x) minx = t2x;
|
|
|
|
if (maxx < t1x) maxx = t1x;
|
|
|
|
if (maxx < t2x) maxx = t2x;
|
|
|
|
drawline(minx, maxx, y, col); // Draw line from min to max points found on the y
|
|
|
|
// Now increase y
|
|
|
|
if (!changed1) t1x += signx1;
|
|
|
|
t1x += t1xp;
|
|
|
|
if (!changed2) t2x += signx2;
|
|
|
|
t2x += t2xp;
|
|
|
|
y += 1;
|
|
|
|
if (y == y2) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Second half
|
|
|
|
dx1 = (int)(x3 - x2); if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
|
|
|
|
else signx1 = 1;
|
|
|
|
dy1 = (int)(y3 - y2);
|
|
|
|
t1x = (int)x2;
|
|
|
|
|
|
|
|
if (dy1 > dx1) { // swap values
|
|
|
|
temp=dy1;dx1=dy1;dy1=temp;
|
|
|
|
changed1 = true;
|
|
|
|
}
|
|
|
|
else changed1 = false;
|
|
|
|
|
|
|
|
e1 = (int)(dx1 >> 1);
|
|
|
|
|
|
|
|
for (int i = 0; i <= dx1; i++) {
|
|
|
|
t1xp = 0; t2xp = 0;
|
|
|
|
if (t1x < t2x) { minx = t1x; maxx = t2x; }
|
|
|
|
else { minx = t2x; maxx = t1x; }
|
|
|
|
// process first line until y value is about to change
|
|
|
|
next3:
|
|
|
|
while (i < dx1) {
|
|
|
|
e1 += dy1;
|
|
|
|
while (e1 >= dx1) {
|
|
|
|
e1 -= dx1;
|
|
|
|
if (changed1) { t1xp = signx1; break; }//t1x += signx1;
|
|
|
|
else break next3;
|
|
|
|
}
|
|
|
|
if (changed1) break;
|
|
|
|
else t1x += signx1;
|
|
|
|
if (i < dx1) i++;
|
|
|
|
}
|
|
|
|
next4:
|
|
|
|
// process second line until y value is about to change
|
|
|
|
while (t2x != x3) {
|
|
|
|
e2 += dy2;
|
|
|
|
while (e2 >= dx2) {
|
|
|
|
e2 -= dx2;
|
|
|
|
if (changed2) t2xp = signx2;
|
|
|
|
else break next4;
|
|
|
|
}
|
|
|
|
if (changed2) break;
|
|
|
|
else t2x += signx2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (minx > t1x) minx = t1x;
|
|
|
|
if (minx > t2x) minx = t2x;
|
|
|
|
if (maxx < t1x) maxx = t1x;
|
|
|
|
if (maxx < t2x) maxx = t2x;
|
|
|
|
drawline(minx, maxx, y,col);
|
|
|
|
if (!changed1) t1x += signx1;
|
|
|
|
t1x += t1xp;
|
|
|
|
if (!changed2) t2x += signx2;
|
|
|
|
t2x += t2xp;
|
|
|
|
y += 1;
|
|
|
|
if (y > y3) return;
|
|
|
|
}
|
|
|
|
}
|
2022-11-28 13:36:26 -06:00
|
|
|
/*
|
|
|
|
* void PixelGameEngine::FillTexturedTriangle(const std::vector<olc::vf2d>& vPoints, std::vector<olc::vf2d> vTex, std::vector<olc::Pixel> vColour, olc::Sprite* sprTex)
|
|
|
|
{
|
|
|
|
olc::vi2d p1 = vPoints[0];
|
|
|
|
olc::vi2d p2 = vPoints[1];
|
|
|
|
olc::vi2d p3 = vPoints[2];
|
|
|
|
|
|
|
|
if (p2.y < p1.y){std::swap(p1.y, p2.y); std::swap(p1.x, p2.x); std::swap(vTex[0].x, vTex[1].x); std::swap(vTex[0].y, vTex[1].y); std::swap(vColour[0], vColour[1]);}
|
|
|
|
if (p3.y < p1.y){std::swap(p1.y, p3.y); std::swap(p1.x, p3.x); std::swap(vTex[0].x, vTex[2].x); std::swap(vTex[0].y, vTex[2].y); std::swap(vColour[0], vColour[2]);}
|
|
|
|
if (p3.y < p2.y){std::swap(p2.y, p3.y); std::swap(p2.x, p3.x); std::swap(vTex[1].x, vTex[2].x); std::swap(vTex[1].y, vTex[2].y); std::swap(vColour[1], vColour[2]);}
|
|
|
|
|
|
|
|
olc::vi2d dPos1 = p2 - p1;
|
|
|
|
olc::vf2d dTex1 = vTex[1] - vTex[0];
|
|
|
|
int dcr1 = vColour[1].r - vColour[0].r;
|
|
|
|
int dcg1 = vColour[1].g - vColour[0].g;
|
|
|
|
int dcb1 = vColour[1].b - vColour[0].b;
|
|
|
|
int dca1 = vColour[1].a - vColour[0].a;
|
|
|
|
|
|
|
|
olc::vi2d dPos2 = p3 - p1;
|
|
|
|
olc::vf2d dTex2 = vTex[2] - vTex[0];
|
|
|
|
int dcr2 = vColour[2].r - vColour[0].r;
|
|
|
|
int dcg2 = vColour[2].g - vColour[0].g;
|
|
|
|
int dcb2 = vColour[2].b - vColour[0].b;
|
|
|
|
int dca2 = vColour[2].a - vColour[0].a;
|
|
|
|
|
|
|
|
float dax_step = 0, dbx_step = 0, dcr1_step = 0, dcr2_step = 0, dcg1_step = 0, dcg2_step = 0, dcb1_step = 0, dcb2_step = 0, dca1_step = 0, dca2_step = 0;
|
|
|
|
olc::vf2d vTex1Step, vTex2Step;
|
|
|
|
|
|
|
|
if (dPos1.y)
|
|
|
|
{
|
|
|
|
dax_step = dPos1.x / (float)abs(dPos1.y);
|
|
|
|
vTex1Step = dTex1 / (float)abs(dPos1.y);
|
|
|
|
dcr1_step = dcr1 / (float)abs(dPos1.y);
|
|
|
|
dcg1_step = dcg1 / (float)abs(dPos1.y);
|
|
|
|
dcb1_step = dcb1 / (float)abs(dPos1.y);
|
|
|
|
dca1_step = dca1 / (float)abs(dPos1.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dPos2.y)
|
|
|
|
{
|
|
|
|
dbx_step = dPos2.x / (float)abs(dPos2.y);
|
|
|
|
vTex2Step = dTex2 / (float)abs(dPos2.y);
|
|
|
|
dcr2_step = dcr2 / (float)abs(dPos2.y);
|
|
|
|
dcg2_step = dcg2 / (float)abs(dPos2.y);
|
|
|
|
dcb2_step = dcb2 / (float)abs(dPos2.y);
|
|
|
|
dca2_step = dca2 / (float)abs(dPos2.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
olc::vi2d vStart;
|
|
|
|
olc::vi2d vEnd;
|
|
|
|
int vStartIdx;
|
|
|
|
|
|
|
|
for (int pass = 0; pass < 2; pass++)
|
|
|
|
{
|
|
|
|
if (pass == 0)
|
|
|
|
{
|
|
|
|
vStart = p1; vEnd = p2; vStartIdx = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dPos1 = p3 - p2;
|
|
|
|
dTex1 = vTex[2] - vTex[1];
|
|
|
|
dcr1 = vColour[2].r - vColour[1].r;
|
|
|
|
dcg1 = vColour[2].g - vColour[1].g;
|
|
|
|
dcb1 = vColour[2].b - vColour[1].b;
|
|
|
|
dca1 = vColour[2].a - vColour[1].a;
|
|
|
|
dcr1_step = 0; dcg1_step = 0; dcb1_step = 0; dca1_step = 0;
|
|
|
|
|
|
|
|
if (dPos2.y) dbx_step = dPos2.x / (float)abs(dPos2.y);
|
|
|
|
if (dPos1.y)
|
|
|
|
{
|
|
|
|
dax_step = dPos1.x / (float)abs(dPos1.y);
|
|
|
|
vTex1Step = dTex1 / (float)abs(dPos1.y);
|
|
|
|
dcr1_step = dcr1 / (float)abs(dPos1.y);
|
|
|
|
dcg1_step = dcg1 / (float)abs(dPos1.y);
|
|
|
|
dcb1_step = dcb1 / (float)abs(dPos1.y);
|
|
|
|
dca1_step = dca1 / (float)abs(dPos1.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
vStart = p2; vEnd = p3; vStartIdx = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dPos1.y)
|
|
|
|
{
|
|
|
|
for (int i = vStart.y; i <= vEnd.y; i++)
|
|
|
|
{
|
|
|
|
int ax = int(vStart.x + (float)(i - vStart.y) * dax_step);
|
|
|
|
int bx = int(p1.x + (float)(i - p1.y) * dbx_step);
|
|
|
|
|
|
|
|
olc::vf2d tex_s(vTex[vStartIdx].x + (float)(i - vStart.y) * vTex1Step.x, vTex[vStartIdx].y + (float)(i - vStart.y) * vTex1Step.y);
|
|
|
|
olc::vf2d tex_e(vTex[0].x + (float)(i - p1.y) * vTex2Step.x, vTex[0].y + (float)(i - p1.y) * vTex2Step.y);
|
|
|
|
|
|
|
|
olc::Pixel col_s(vColour[vStartIdx].r + uint8_t((float)(i - vStart.y) * dcr1_step), vColour[vStartIdx].g + uint8_t((float)(i - vStart.y) * dcg1_step),
|
|
|
|
vColour[vStartIdx].b + uint8_t((float)(i - vStart.y) * dcb1_step), vColour[vStartIdx].a + uint8_t((float)(i - vStart.y) * dca1_step));
|
|
|
|
|
|
|
|
olc::Pixel col_e(vColour[0].r + uint8_t((float)(i - p1.y) * dcr2_step), vColour[0].g + uint8_t((float)(i - p1.y) * dcg2_step),
|
|
|
|
vColour[0].b + uint8_t((float)(i - p1.y) * dcb2_step), vColour[0].a + uint8_t((float)(i - p1.y) * dca2_step));
|
|
|
|
|
|
|
|
if (ax > bx) { std::swap(ax, bx); std::swap(tex_s, tex_e); std::swap(col_s, col_e); }
|
|
|
|
|
|
|
|
float tstep = 1.0f / ((float)(bx - ax));
|
|
|
|
float t = 0.0f;
|
|
|
|
|
|
|
|
for (int j = ax; j < bx; j++)
|
|
|
|
{
|
|
|
|
olc::Pixel pixel = PixelLerp(col_s, col_e, t);
|
|
|
|
if (sprTex != nullptr) pixel *= sprTex->Sample(tex_s.lerp(tex_e, t));
|
|
|
|
Draw(j, i, pixel);
|
|
|
|
t += tstep;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2022-11-28 13:27:45 -06:00
|
|
|
|
2022-11-28 11:48:13 -06:00
|
|
|
public void Clear(Color col){
|
|
|
|
for (int y=0;y<JavaProjectTemplate.WINDOW_HEIGHT;y++) {
|
|
|
|
for (int x=0;x<JavaProjectTemplate.WINDOW_WIDTH;x++) {
|
2022-11-28 12:17:28 -06:00
|
|
|
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
|
2022-11-28 11:48:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-28 10:29:34 -06:00
|
|
|
}
|