From 057ef44afb34cc21361dc9c46cb2fbf0d0fa75f6 Mon Sep 17 00:00:00 2001 From: Joshua Sigona Date: Sun, 7 Nov 2021 09:47:03 +0900 Subject: [PATCH] Threading. --- src/sig/Panel.java | 89 ++++++++++++++++++++++++++-------------- src/sig/SigRenderer.java | 14 +++---- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/sig/Panel.java b/src/sig/Panel.java index 3c82e02..603eec6 100644 --- a/src/sig/Panel.java +++ b/src/sig/Panel.java @@ -11,6 +11,7 @@ import java.awt.image.MemoryImageSource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; import java.awt.image.ColorModel; import java.awt.GraphicsEnvironment; import java.awt.GraphicsConfiguration; @@ -26,7 +27,13 @@ public class Panel extends JPanel implements Runnable { private MemoryImageSource mImageProducer; private ColorModel cm; private Thread thread; + Thread workerThread; List accumulatedTris = new ArrayList(); + public static ConcurrentLinkedQueue accumulatedTris1 = new ConcurrentLinkedQueue<>(); + public static ConcurrentLinkedQueue accumulatedTris2 = new ConcurrentLinkedQueue<>(); + boolean renderFirst=false; + boolean lastRender=renderFirst; + boolean renderNeeded=false; long profileStartTime; public Panel() { @@ -90,7 +97,7 @@ public class Panel extends JPanel implements Runnable { } } - accumulatedTris.clear(); + //accumulatedTris2.clear(); //Matrix matRotZ = Matrix.MakeRotationZ(fTheta*0.5f),matRotX = Matrix.MakeRotationX(fTheta); Matrix matRotZ = Matrix.IDENTITY; @@ -109,32 +116,51 @@ public class Panel extends JPanel implements Runnable { Matrix matCamera = Matrix.PointAt(SigRenderer.vCamera, vTarget, vUp); Matrix matView = Matrix.QuickInverse(matCamera); - for (String key : SigRenderer.blockGrid.keySet()) { - Block b = SigRenderer.blockGrid.get(key); - if (!b.neighbors.UP) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(8), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(9), accumulatedTris); - } - if (!b.neighbors.DOWN) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(10), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(11), accumulatedTris); - } - if (!b.neighbors.LEFT) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(6), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(7), accumulatedTris); - } - if (!b.neighbors.RIGHT) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(2), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(3), accumulatedTris); - } - if (!b.neighbors.FORWARD) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(4), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(5), accumulatedTris); - } - if (!b.neighbors.BACKWARD) { - prepareTriForRender(matWorld, matView, b.block.triangles.get(0), accumulatedTris); - prepareTriForRender(matWorld, matView, b.block.triangles.get(1), accumulatedTris); - } + if (workerThread==null||(!workerThread.isAlive()&&renderNeeded)) { + renderFirst=!renderFirst; + final Matrix matWorld2 = matWorld; + workerThread = new Thread() { + @Override + public void run() { + ConcurrentLinkedQueue newTris = new ConcurrentLinkedQueue<>(); + for (String key : SigRenderer.blockGrid.keySet()) { + Block b = SigRenderer.blockGrid.get(key); + if (!b.neighbors.UP) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(8), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(9), newTris); + } + if (!b.neighbors.DOWN) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(10), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(11), newTris); + } + if (!b.neighbors.LEFT) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(6), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(7), newTris); + } + if (!b.neighbors.RIGHT) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(2), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(3), newTris); + } + if (!b.neighbors.FORWARD) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(4), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(5), newTris); + } + if (!b.neighbors.BACKWARD) { + prepareTriForRender(matWorld2, matView, b.block.triangles.get(0), newTris); + prepareTriForRender(matWorld2, matView, b.block.triangles.get(1), newTris); + } + } + if (renderFirst) { + accumulatedTris2.clear(); + accumulatedTris2.addAll(newTris); + } else { + accumulatedTris1.clear(); + accumulatedTris1.addAll(newTris); + } + renderNeeded=false; + } + }; + workerThread.start(); } if (SigRenderer.PROFILING) { System.out.println((System.currentTimeMillis()-profileStartTime)+"ms");profileStartTime=System.currentTimeMillis(); @@ -150,8 +176,8 @@ public class Panel extends JPanel implements Runnable { SigRenderer.tempAnswer=null; long totalTime=0; long startTime2=0; - for (Triangle t : accumulatedTris) { - + ConcurrentLinkedQueue currentRender = (renderFirst)?accumulatedTris1:accumulatedTris2; + for (Triangle t : currentRender) { Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; List triList = new ArrayList<>(); triList.add(t); @@ -180,7 +206,7 @@ public class Panel extends JPanel implements Runnable { } for (Triangle tt : triList) { if (tt.tex!=null) { - tt.unmodifiedTri.nextRenderTime=System.currentTimeMillis()+200; + //tt.unmodifiedTri.nextRenderTime=System.currentTimeMillis()+200; DrawUtils.TexturedTriangle(p, (int)tt.A.x,(int)tt.A.y,tt.T.u,tt.T.v,tt.T.w, (int)tt.B.x,(int)tt.B.y,tt.U.u,tt.U.v,tt.U.w, @@ -197,6 +223,7 @@ public class Panel extends JPanel implements Runnable { totalTime+=System.nanoTime()-startTime2; } } + renderNeeded=true; for (int x=0;x accumulatedTris) { + private void prepareTriForRender(Matrix matWorld, Matrix matView, Triangle t, ConcurrentLinkedQueue accumulatedTris) { if (t.nextRenderTime<=System.currentTimeMillis()) { Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle(); diff --git a/src/sig/SigRenderer.java b/src/sig/SigRenderer.java index 36b9724..89f20a4 100644 --- a/src/sig/SigRenderer.java +++ b/src/sig/SigRenderer.java @@ -19,6 +19,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.awt.Toolkit; import java.awt.BorderLayout; @@ -26,8 +28,6 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static boolean WIREFRAME = false; public static boolean PROFILING = false; - - public static List triRender = new ArrayList<>(); public static int SCREEN_WIDTH=1280; public static int SCREEN_HEIGHT=720; public final static long TIMEPERTICK = 16666667l; @@ -35,8 +35,8 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static float DRAWLOOPTIME=0; public static final float RESOLUTION=1; public static float rot = (float)Math.PI/4; //In radians. - public static Map blockGrid = new HashMap<>(); - public static HashMap renderMap = new HashMap<>(); + public static ConcurrentHashMap blockGrid = new ConcurrentHashMap<>(); + public static ConcurrentHashMap renderMap = new ConcurrentHashMap<>(); public static List pixels; @@ -46,7 +46,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH; public static Matrix matProj = Matrix.MakeProjection(fFov,fAspectRatio,fNear,fFar); - public static Vector vCamera = new Vector(63.5f,20f,63.5f); + public static Vector vCamera = new Vector(31.5f,20f,31.5f); public static Vector vLookDir = new Vector(0,0,1); public static float yaw = (float)(-Math.PI/8); public static float pitch = (float)(-Math.PI/6); @@ -110,8 +110,8 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene SigRenderer(JFrame f) { //cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false)); Random r = new Random(438107); - for (int x=0;x<64;x++) { - for (int z=0;z<64;z++) { + for (int x=0;x<256;x++) { + for (int z=0;z<256;z++) { if (Math.random()<=0.5) { addBlock(new Vector(x,0,z),BlockType.DIRT); } else {