diff --git a/src/main/java/uk/org/floop/epq3d/App.java b/src/main/java/uk/org/floop/epq3d/App.java index 1219fc8..b358050 100644 --- a/src/main/java/uk/org/floop/epq3d/App.java +++ b/src/main/java/uk/org/floop/epq3d/App.java @@ -28,7 +28,6 @@ window.setLocationRelativeTo(null); // display the window window.setVisible(true); - long i = 2147483648L; } public static void main(String[] args) { diff --git a/src/main/java/uk/org/floop/epq3d/Face.java b/src/main/java/uk/org/floop/epq3d/Face.java index 6dcd904..60e122e 100644 --- a/src/main/java/uk/org/floop/epq3d/Face.java +++ b/src/main/java/uk/org/floop/epq3d/Face.java @@ -38,7 +38,7 @@ tri.invalidate(); } } - public int draw(BufferedImage img, BufferedImage zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){ + public int draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){ if(!isInitialised){ throw new RuntimeException("Face not initialised"); } @@ -200,7 +200,7 @@ // create and draw new triangle Triangle newTri; newTri = new Triangle(newPoint1.project(FPDis, scrX, scrY), newPoint2.project(FPDis, scrX, scrY), oldPoint.project(FPDis, scrX, scrY), - new boolean[]{true, true, true}, + new boolean[]{false, false, false}, tris[tri_i].texture, tris[tri_i].perspectiveMappingMatrix); newTri.draw(img, zBuf, FPDis, scrX, scrY); @@ -210,7 +210,6 @@ return numberOfPixels; } - /* if (valid) { //drawTris(img, zBuf, FPDis, scrX, scrY);} @@ -512,7 +511,7 @@ // should decrease processing time of each pixel by a lot } - private void bakePerspectiveMatrices(BufferedImage img, BufferedImage zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){ + private void bakePerspectiveMatrices(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY){ // calculate matrix which converts 2d points into 3d points { // first, we get the rotated plane points and normal points @@ -615,7 +614,6 @@ // real01Vec.x = result[0];real01Vec.y = result[1];real01Vec.z = result[2]; // result = zMat.multiplyPoint3raw(real02Vec.x, real02Vec.y, real02Vec.z); // real02Vec.x = result[0];real02Vec.y = result[1];real02Vec.z = result[2]; -// // invert the Z matrix (todo cleanup) // zMat.setItems(new double[][]{ // {Math.cos(-zAng), Math.sin(-zAng), 0, 0}, // {-Math.sin(-zAng), Math.cos(-zAng), 0, 0}, diff --git a/src/main/java/uk/org/floop/epq3d/Object3d.java b/src/main/java/uk/org/floop/epq3d/Object3d.java index 241dc2e..b057b7a 100644 --- a/src/main/java/uk/org/floop/epq3d/Object3d.java +++ b/src/main/java/uk/org/floop/epq3d/Object3d.java @@ -28,7 +28,7 @@ face.invalidate(); } } - public void draw(BufferedImage img, BufferedImage zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY, Point3D playerPos){ + public void draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, double FPDis, int scrX, int scrY, Point3D playerPos){ int iterator = 0; for (Face face: faces) { diff --git a/src/main/java/uk/org/floop/epq3d/ObjectCollection.java b/src/main/java/uk/org/floop/epq3d/ObjectCollection.java index 5e2cd6b..1513f94 100644 --- a/src/main/java/uk/org/floop/epq3d/ObjectCollection.java +++ b/src/main/java/uk/org/floop/epq3d/ObjectCollection.java @@ -31,7 +31,7 @@ } } - public void draw(BufferedImage img, BufferedImage zBuf, BufferedImage debugImg, Matrix camMatrix, Point3D playerPos, Plane[] frustumPlanes, double FPDis, int scrX, int scrY){ + public void draw(int[][] img, int[][] zBuf, BufferedImage debugImg, Matrix camMatrix, Point3D playerPos, Plane[] frustumPlanes, double FPDis, int scrX, int scrY){ for (Object3d object: objects) { boolean draw = true; diff --git a/src/main/java/uk/org/floop/epq3d/Screen.java b/src/main/java/uk/org/floop/epq3d/Screen.java index 7a56f29..4a79d08 100644 --- a/src/main/java/uk/org/floop/epq3d/Screen.java +++ b/src/main/java/uk/org/floop/epq3d/Screen.java @@ -15,7 +15,12 @@ private final Point2D mouseRel = new Point2D(0,0); private final Cursor invisibleCursor; + // mainCollection stores all the background information in the scene public ObjectCollection mainCollection; + // stores the skybox + public Object3d skyBox; + // stores the 2d information on the HUD + public BufferedImage debugImg; public JsonWriter json; // testing\ @@ -38,9 +43,9 @@ // controls the delay between each tick in ms private final int DELAY = 25; // controls the size of the board - public static final int TILE_SIZE = 50; - public static final int ROWS = 12; - public static final int COLUMNS = 18; + public static final int scrX = 900; + public static final int scrY = 600; + // suppress serialization warning private static final long serialVersionUID = 490905409104883233L; @@ -53,7 +58,7 @@ mainCollection = _mainCollection; // set the game board size - setPreferredSize(new Dimension(TILE_SIZE * COLUMNS, TILE_SIZE * ROWS)); + setPreferredSize(new Dimension(scrX, scrY)); // set the game board background color setBackground(new Color(232, 232, 232)); // hide the mouse cursor (https://stackoverflow.com/questions/191592/how-do-i-get-rid-of-the-mouse-cursor-in-full-screen-exclusive-mode) @@ -63,7 +68,7 @@ invisibleCursor = toolkit.createCustomCursor(cursorImage, hotSpot, "InvisibleCursor"); // initialize the game state - player = new Player(TILE_SIZE*COLUMNS, TILE_SIZE*ROWS); + player = new Player(scrX, scrY); // this frameTimer will call the actionPerformed() method every DELAY ms frameTimer = new Timer(DELAY, this); frameTimer.start(); @@ -93,11 +98,11 @@ Toolkit.getDefaultToolkit().sync(); } private void drawScreen(Graphics g) { - BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB ); - BufferedImage zBuf = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); - BufferedImage debugImg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + int[][] img = new int[scrX][scrY]; + //BufferedImage zBuf = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + int[][] zBuf = new int[scrX][scrY]; + debugImg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); debugImg.createGraphics(); - g.setColor(Color.white); // System.out.println(zBuf.getRGB(0,0)); // zBuf.setRGB(0,0, 100); @@ -139,47 +144,62 @@ mainCollection.invalidate(true); mainCollection.draw(img, zBuf, debugImg, player.camMatrix, player.getPos(), player.frustumPlanes, player.Fpdis, getWidth(), getHeight()); - g.drawImage(img, 0, 0, this); + long time = System.currentTimeMillis(); + BufferedImage bufImg = new BufferedImage(scrX, scrY, BufferedImage.TYPE_INT_ARGB); + for(int x = 0; x < scrX; x +=1){ + for(int y = 0; y < scrY; y += 1){ + bufImg.setRGB(x, y, img[x][y]); + } + } + time = (System.currentTimeMillis() - time); + g.drawImage(bufImg, 0, 0, this); // DEBUG DRAWING + boolean debug = false; { - debugImg.getGraphics().drawString(Math.round(1000 / (float) (System.currentTimeMillis() - lastTime)) + " fps", 10, 10); - debugImg.getGraphics().drawString("fpPos: " + - String.format("%.2f", player.FPWorldPos.x) + " " + - String.format("%.2f", player.FPWorldPos.y) + " " + - String.format("%.2f", player.FPWorldPos.z) + " ", 100, 30); - g.drawImage(debugImg, 0, 0, this); - debugImg.getGraphics().drawString("playerPos: " + - String.format("%.2f", player.getPos().x) + " " + - String.format("%.2f", player.getPos().y) + " " + - String.format("%.2f", player.getPos().z) + " ", 100, 50); - debugImg.getGraphics().drawString("rotation: " + - Math.round(Math.toDegrees(player.getRot().x)) + " " + - Math.round(Math.toDegrees(player.getRot().y)) + " " + - Math.round(Math.toDegrees(player.getRot().z)) + " ", 300, 50); - debugImg.getGraphics().drawString("viewVec: " + - String.format("%.2f", player.viewVector.x) + " " + - String.format("%.2f", player.viewVector.y) + " " + - String.format("%.2f", player.viewVector.z) + " ", 100, 70); - for (int i = 0; i < 4; i += 1) { - debugImg.getGraphics().drawString("camPoint " + i + ": " + - String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().x) + " " + - String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().y) + " " + - String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().z), 10, 90 + 20 * i); - } - for (int i = 0; i < 6; i += 1) { - debugImg.getGraphics().drawString("plane " + i + ": " + - String.format("%.2f", player.frustumPlanes[i].mainPoint.x) + " " + - String.format("%.2f", player.frustumPlanes[i].mainPoint.y) + " " + - String.format("%.2f", player.frustumPlanes[i].mainPoint.z) + ", normal: " + - String.format("%.2f", player.frustumPlanes[i].normalVector.x) + " " + - String.format("%.2f", player.frustumPlanes[i].normalVector.y) + " " + - String.format("%.2f", player.frustumPlanes[i].normalVector.z), 10, 170 + 20 * i); + debugImg.getGraphics().setColor(new Color(255,255,255,0)); + //debugImg.getGraphics().drawString(Math.round(1000 / (float) (System.currentTimeMillis() - lastTime)) + " fps", 10, 10); + debugImg.getGraphics().drawString("FrameTime: " + (System.currentTimeMillis() - lastTime) + " millis", 10, 10); + debugImg.getGraphics().drawString(time + " millis", 60, 20); + if(debug) { + debugImg.getGraphics().drawString("fpPos: " + + String.format("%.2f", player.FPWorldPos.x) + " " + + String.format("%.2f", player.FPWorldPos.y) + " " + + String.format("%.2f", player.FPWorldPos.z) + " ", 100, 30); + g.drawImage(debugImg, 0, 0, this); + debugImg.getGraphics().drawString("playerPos: " + + String.format("%.2f", player.getPos().x) + " " + + String.format("%.2f", player.getPos().y) + " " + + String.format("%.2f", player.getPos().z) + " ", 100, 50); + debugImg.getGraphics().drawString("rotation: " + + Math.round(Math.toDegrees(player.getRot().x)) + " " + + Math.round(Math.toDegrees(player.getRot().y)) + " " + + Math.round(Math.toDegrees(player.getRot().z)) + " ", 300, 50); + debugImg.getGraphics().drawString("viewVec: " + + String.format("%.2f", player.viewVector.x) + " " + + String.format("%.2f", player.viewVector.y) + " " + + String.format("%.2f", player.viewVector.z) + " ", 100, 70); + for (int i = 0; i < 4; i += 1) { + debugImg.getGraphics().drawString("camPoint " + i + ": " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().x) + " " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().y) + " " + + String.format("%.2f", player.ScreenCornerPosS[i].getRotatedPoint().z), 10, 90 + 20 * i); + } + for (int i = 0; i < 6; i += 1) { + debugImg.getGraphics().drawString("plane " + i + ": " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.x) + " " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.y) + " " + + String.format("%.2f", player.frustumPlanes[i].mainPoint.z) + ", normal: " + + String.format("%.2f", player.frustumPlanes[i].normalVector.x) + " " + + String.format("%.2f", player.frustumPlanes[i].normalVector.y) + " " + + String.format("%.2f", player.frustumPlanes[i].normalVector.z), 10, 170 + 20 * i); + } } // write debug overlay g.drawImage(debugImg, 0, 0, this); lastTime = System.currentTimeMillis(); } + // HTTPPost post = new HTTPPost(); // // json WRITING // json = new JsonWriter(); diff --git a/src/main/java/uk/org/floop/epq3d/Triangle.java b/src/main/java/uk/org/floop/epq3d/Triangle.java index 412da4c..902f69a 100644 --- a/src/main/java/uk/org/floop/epq3d/Triangle.java +++ b/src/main/java/uk/org/floop/epq3d/Triangle.java @@ -1,7 +1,6 @@ package uk.org.floop.epq3d; import java.awt.*; -import java.awt.image.BufferedImage; public class Triangle{ public Point2D point1; @@ -37,7 +36,7 @@ perspectiveMappingMatrix = mapMatrix; } // returns int for debug - public int draw(BufferedImage img, BufferedImage zBuf, double FPDis, int scrX, int scrY){ + public int draw(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY){ // long lastMillis; @@ -53,8 +52,8 @@ for(int x = min.x+1; x <= max.x; x += 1) { while(x-1 == point1[0]) { if(LineLong.isDrawn && // draw line pixels if needed, and on screen - point1[0] > 0 && point1[1] > 0 && point1[0] < img.getWidth() && point1[1] < img.getHeight()){ - img.setRGB(point1[0], point1[1], Color.HSBtoRGB(0, 1, 1)); + point1[0] > 0 && point1[1] > 0 && point1[0] < scrX && point1[1] < scrY){ + img[point1[0]][point1[1]] = Color.HSBtoRGB(0, 1, 1); } try { // this error seems to be thrown randomly, for various reasons // todo fix point1 = LineLong.nextPix(); @@ -67,8 +66,8 @@ if (currentLine == 'A') { try{ if(LineA.isDrawn && // draw line pixels if needed, and on screen - point2[0] > 0 && point2[1] > 0 && point2[0] < img.getWidth() && point2[1] < img.getHeight()){ - img.setRGB(point2[0], point2[1], Color.HSBtoRGB(0f, 1, 1)); + point2[0] > 0 && point2[1] > 0 && point2[0] < scrX && point2[1] < scrY){ + img[point2[0]][point2[1]] = Color.HSBtoRGB(0, 1, 1); } point2 = LineA.nextPix(); } @@ -79,24 +78,24 @@ } else { if(LineB.isDrawn && // draw line pixels if needed, and on screen - point2[0] > 0 && point2[1] > 0 && point2[0] < img.getWidth() && point2[1] < img.getHeight()){ - img.setRGB(point2[0], point2[1], Color.HSBtoRGB(0f, 1, 1)); + point2[0] > 0 && point2[1] > 0 && point2[0] < scrX && point2[1] < scrY){ + img[point2[0]][point2[1]] = Color.HSBtoRGB(0, 1, 1); } point2 = LineB.nextPix(); } } // cancel drawing if the x value of the triangle is out of bounds - if (x >= img.getWidth()) {break;} + if (x >= scrX) {break;} if (x > 0) { // check which way to loop // TODO - work out a way of not needing to test for this every time if (point1[1] < point2[1]) { - for (int y = Math.max(point1[1], 0); y <= Math.min(point2[1], img.getHeight() - 1); y += 1) { + for (int y = Math.max(point1[1], 0); y <= Math.min(point2[1], scrY - 1); y += 1) { // function only exists so I don't have to copy paste code everywhere. drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x, y, point1[1], point2[1]); } } else { - for (int y = Math.max(point2[1], 0); y <= Math.min(point1[1], img.getHeight() - 1); y += 1) { + for (int y = Math.max(point2[1], 0); y <= Math.min(point1[1], scrY - 1); y += 1) { drawPix(img, zBuf, FPDis, scrX, scrY, currentLine, x,y, point1[1], point2[1]); } } @@ -150,7 +149,7 @@ // assign points to lines is_initialised = true; } - private void drawPix(BufferedImage img, BufferedImage zBuf, double FPDis, int scrX, int scrY, char currentLine, int x, int y, int y1, int y2){ + private void drawPix(int[][] img, int[][] zBuf, double FPDis, int scrX, int scrY, char currentLine, int x, int y, int y1, int y2){ // find Z coordinate of pixel double z1 = LineLong.getZVal(x); double z2; if(currentLine=='A'){z2=LineA.getZVal(x);} else{z2=LineB.getZVal(x);} @@ -160,9 +159,9 @@ // not the best mapping but it's probably good enough int newZ = (int)((2147483648L/ZVal)); // if the new Z value is greater than the existing Z value on the buffer, the new pixel is calculated and drawn - if(zBuf.getRGB(x, y) == Color.HSBtoRGB(0, 0, 0) || - newZ > zBuf.getRGB(x, y)){ //newZ > zBuf.getRGB(x, y) || - zBuf.setRGB(x, y, newZ); + if(zBuf[x][y] == Color.HSBtoRGB(0, 0, 0) || + newZ > zBuf[x][y]){ //newZ > zBuf.getRGB(x, y) || + zBuf[x][y] = newZ; result = new Point3D(0,0,0); //perspectiveMappingMatrix.multiplyPoint3to(new Point3D(x, y, 0), result); // project result @@ -172,7 +171,7 @@ } else { throw new RuntimeException("Textures are not supported"); } - img.setRGB(x, y, pixColor.getRGB()); + img[x][y] = pixColor.getRGB(); // result.projectOn(FPDis, scrX, scrY, result2); // int colour = texture.img.getRGB( // Math.floorMod((result2.x), texture.img.getWidth()), diff --git a/src/main/java/uk/org/floop/epq3d/Vector3D.java b/src/main/java/uk/org/floop/epq3d/Vector3D.java index 19d26c1..735a1ec 100644 --- a/src/main/java/uk/org/floop/epq3d/Vector3D.java +++ b/src/main/java/uk/org/floop/epq3d/Vector3D.java @@ -16,7 +16,7 @@ z = 0; } public void createFrom2Points(Point3D start, Point3D end){ - x = end.x - start.x; + x = end.x - start.x; y = end.y - start.y; z = end.z - start.z; }