diff --git a/src/sig/Block.java b/src/sig/Block.java index 4085c40..a828b18 100644 --- a/src/sig/Block.java +++ b/src/sig/Block.java @@ -20,58 +20,22 @@ public class Block { } public void updateFaces() { if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y+1)+"_"+pos.z)) { - neighbors.UP=true; - if (block.triangles.get(Texture.TOP).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).block.triangles.get(Texture.BOTTOM).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).neighbors.DOWN=true; - } else - if (block.triangles.get(Texture.TOP).tex.hasTransparency&&!SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).block.triangles.get(Texture.BOTTOM).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).neighbors.DOWN=false; - } + neighbors.UP=SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).neighbors.DOWN=block.triangles.get(Texture.TOP).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).block.triangles.get(Texture.BOTTOM).tex.hasTransparency&&block.triangles.get(Texture.TOP).tex.hasTranslucency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).block.triangles.get(Texture.BOTTOM).tex.hasTranslucency; } if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y-1)+"_"+pos.z)) { - neighbors.DOWN=true; - if (block.triangles.get(Texture.BOTTOM).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).block.triangles.get(Texture.TOP).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).neighbors.UP=true; - } else - if (block.triangles.get(Texture.BOTTOM).tex.hasTransparency&&!SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).block.triangles.get(Texture.TOP).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).neighbors.UP=false; - } + neighbors.DOWN=SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).neighbors.UP=block.triangles.get(Texture.BOTTOM).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).block.triangles.get(Texture.TOP).tex.hasTransparency&&block.triangles.get(Texture.BOTTOM).tex.hasTranslucency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).block.triangles.get(Texture.TOP).tex.hasTranslucency; } if (SigRenderer.blockGrid.containsKey((pos.x-1)+"_"+(pos.y)+"_"+pos.z)) { - neighbors.LEFT=true; - if (block.triangles.get(Texture.WEST).tex.hasTransparency==SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.EAST).tex.hasTransparency) { - SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).neighbors.RIGHT=true; - } else - if (block.triangles.get(Texture.WEST).tex.hasTransparency&&!SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.EAST).tex.hasTransparency) { - SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).neighbors.RIGHT=false; - } + neighbors.LEFT=SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).neighbors.RIGHT=block.triangles.get(Texture.WEST).tex.hasTransparency==SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.EAST).tex.hasTransparency&&block.triangles.get(Texture.WEST).tex.hasTranslucency==SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.EAST).tex.hasTranslucency; } if (SigRenderer.blockGrid.containsKey((pos.x+1)+"_"+(pos.y)+"_"+pos.z)) { - neighbors.RIGHT=true; - if (block.triangles.get(Texture.EAST).tex.hasTransparency==SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.WEST).tex.hasTransparency) { - SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).neighbors.LEFT=true; - } else - if (block.triangles.get(Texture.EAST).tex.hasTransparency&&!SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.WEST).tex.hasTransparency) { - SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).neighbors.LEFT=false; - } + neighbors.RIGHT=SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).neighbors.LEFT=block.triangles.get(Texture.EAST).tex.hasTransparency==SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.WEST).tex.hasTransparency&&block.triangles.get(Texture.EAST).tex.hasTranslucency==SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).block.triangles.get(Texture.WEST).tex.hasTranslucency; } if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z+1))) { - neighbors.FORWARD=true; - if (block.triangles.get(Texture.SOUTH).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).block.triangles.get(Texture.NORTH).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).neighbors.BACKWARD=true; - } else - if (block.triangles.get(Texture.SOUTH).tex.hasTransparency&&!SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).block.triangles.get(Texture.NORTH).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).neighbors.BACKWARD=false; - } + neighbors.FORWARD=SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).neighbors.BACKWARD=block.triangles.get(Texture.SOUTH).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).block.triangles.get(Texture.NORTH).tex.hasTransparency&&block.triangles.get(Texture.SOUTH).tex.hasTranslucency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).block.triangles.get(Texture.NORTH).tex.hasTranslucency; } if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z-1))) { - neighbors.BACKWARD=true; - if (block.triangles.get(Texture.NORTH).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).block.triangles.get(Texture.SOUTH).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).neighbors.FORWARD=true; - } else - if (block.triangles.get(Texture.NORTH).tex.hasTransparency&&!SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).block.triangles.get(Texture.SOUTH).tex.hasTransparency) { - SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).neighbors.FORWARD=false; - } + neighbors.BACKWARD=SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).neighbors.FORWARD=block.triangles.get(Texture.NORTH).tex.hasTransparency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).block.triangles.get(Texture.SOUTH).tex.hasTransparency&&block.triangles.get(Texture.NORTH).tex.hasTranslucency==SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).block.triangles.get(Texture.SOUTH).tex.hasTranslucency; } } @Override diff --git a/src/sig/Panel.java b/src/sig/Panel.java index a6e5ed8..5937510 100644 --- a/src/sig/Panel.java +++ b/src/sig/Panel.java @@ -10,13 +10,17 @@ import java.awt.Image; import java.awt.image.MemoryImageSource; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import java.awt.image.ColorModel; import java.awt.GraphicsEnvironment; import java.awt.GraphicsConfiguration; import java.awt.Toolkit; +import java.util.Queue; public class Panel extends JPanel implements Runnable { long startTime = System.nanoTime(); @@ -75,6 +79,7 @@ public class Panel extends JPanel implements Runnable { } SigRenderer.depthBuffer = new float[width*height]; SigRenderer.depthBuffer_tri = new Triangle[width*height]; + SigRenderer.translucencyBuffer = new boolean[width*height]; } /** * Do your draws in here !! @@ -95,6 +100,7 @@ public class Panel extends JPanel implements Runnable { p[ (int)(x*SigRenderer.RESOLUTION) + (int)(y*SigRenderer.RESOLUTION) * width] = 0; SigRenderer.depthBuffer[x+y*width]=0; SigRenderer.depthBuffer_tri[x+y*width]=null; + SigRenderer.translucencyBuffer[x+y*width]=false; } } @@ -234,14 +240,131 @@ public class Panel extends JPanel implements Runnable { } } renderNeeded=true; + boolean translucencyDetected=false; for (int x=0;x)currentRender, new Comparator() { + @Override + public int compare(Triangle t1, Triangle t2) { + float z1=(t1.A.z+t1.B.z+t1.C.z)/3f; + float z2=(t2.A.z+t2.B.z+t2.C.z)/3f; + return (z1 triList = new ArrayList<>(); + triList.add(t); + int newTriangles=1; + for (int pl=0;pl<4;pl++) { + int trisToAdd=0; + while (newTriangles>0) { + clipped = new Triangle[]{new Triangle(),new Triangle()}; + Triangle test = triList.remove(0); + newTriangles--; + switch (pl) { + case 0:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,0,0),new Vector(0,1,0),test,clipped);}break; + case 1:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,getHeight()-1f,0),new Vector(0,-1,0),test,clipped);}break; + case 2:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,0,0),new Vector(1,0,0),test,clipped);}break; + case 3:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(getWidth()-1f,0,0),new Vector(-1,0,0),test,clipped);}break; + } + for (int w=0;w>16,tt,DrawUtils.IGNORE_TRANSLUCENT_RENDERING); + } else { + DrawUtils.FillTriangle(p,(int)tt.A.x,(int)tt.A.y,(int)tt.B.x,(int)tt.B.y,(int)tt.C.x,(int)tt.C.y,tt.getColor()); + } + if (SigRenderer.WIREFRAME) { + DrawUtils.DrawTriangle(p,(int)tt.A.x,(int)tt.A.y,(int)tt.B.x,(int)tt.B.y,(int)tt.C.x,(int)tt.C.y,Color.WHITE.getRGB()); + } + } + if (SigRenderer.PROFILING) { + totalTime+=System.nanoTime()-startTime2; + } + } + for (Triangle t : currentRender) { + Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; + List triList = new ArrayList<>(); + triList.add(t); + int newTriangles=1; + for (int pl=0;pl<4;pl++) { + int trisToAdd=0; + while (newTriangles>0) { + clipped = new Triangle[]{new Triangle(),new Triangle()}; + Triangle test = triList.remove(0); + newTriangles--; + switch (pl) { + case 0:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,0,0),new Vector(0,1,0),test,clipped);}break; + case 1:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,getHeight()-1f,0),new Vector(0,-1,0),test,clipped);}break; + case 2:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(0,0,0),new Vector(1,0,0),test,clipped);}break; + case 3:{trisToAdd = Triangle.ClipAgainstPlane(new Vector(getWidth()-1f,0,0),new Vector(-1,0,0),test,clipped);}break; + } + for (int w=0;w>16,tt,DrawUtils.TRANSLUCENT_ONLY_RENDERING); + } else { + DrawUtils.FillTriangle(p,(int)tt.A.x,(int)tt.A.y,(int)tt.B.x,(int)tt.B.y,(int)tt.C.x,(int)tt.C.y,tt.getColor()); + } + if (SigRenderer.WIREFRAME) { + DrawUtils.DrawTriangle(p,(int)tt.A.x,(int)tt.A.y,(int)tt.B.x,(int)tt.B.y,(int)tt.C.x,(int)tt.C.y,Color.WHITE.getRGB()); + } + } + if (SigRenderer.PROFILING) { + totalTime+=System.nanoTime()-startTime2; + } + } + + for (int x=0;x blockTextures = new HashMap(); @@ -117,8 +120,12 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene } for (int x=0;x<64;x++) { - for (int y=0;y<5;y++) { - addBlock(new Vector(x,y,16),BlockType.GLASS); + for (int y=1;y<5;y++) { + if (x%8>2&&x%8<6&&y>1&&y<4) { + addBlock(new Vector(x,y,16),BlockType.GLASS); + } else { + addBlock(new Vector(x,y,16),BlockType.ICE); + } } } @@ -171,15 +178,19 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene WritableRaster r = img.getRaster(); for (TextureType tt : TextureType.values()) { int[] pixelData = new int[tt.texWidth*BLOCK_WIDTH*tt.texHeight*BLOCK_HEIGHT]; - Texture tex = new Texture(pixelData,tt.texWidth*BLOCK_WIDTH,tt.texHeight*BLOCK_HEIGHT); + Texture tex = new Texture(pixelData,tt.texWidth*BLOCK_WIDTH,tt.texHeight*BLOCK_HEIGHT,tt); int startX=tt.texX*BLOCK_WIDTH; int startY=tt.texY*BLOCK_HEIGHT; for (int x=0;x0) { + tex.hasTranslucency=true; + } else { + tex.hasTransparency=true; + } } } } diff --git a/src/sig/Texture.java b/src/sig/Texture.java index f69b6b2..e5fe24c 100644 --- a/src/sig/Texture.java +++ b/src/sig/Texture.java @@ -14,6 +14,8 @@ public class Texture{ int width; int height; public boolean hasTransparency=false; + public boolean hasTranslucency=false; + TextureType type; public Texture(File f) { try { @@ -41,10 +43,11 @@ public class Texture{ public static final int TOP = 8; public static final int BOTTOM = 10; - public Texture(int[] tex,int width,int height) { + public Texture(int[] tex,int width,int height,TextureType type) { this.tex=tex; this.width=width; this.height=height; + this.type=type; } public int getColor(float u,float v,float mult) { diff --git a/src/sig/utils/DrawUtils.java b/src/sig/utils/DrawUtils.java index 324563f..03ce004 100644 --- a/src/sig/utils/DrawUtils.java +++ b/src/sig/utils/DrawUtils.java @@ -9,16 +9,27 @@ import sig.Texture; import sig.Triangle; public class DrawUtils { + final public static int NORMAL_RENDERING = 0; + final public static int IGNORE_TRANSLUCENT_RENDERING = 1; + final public static int TRANSLUCENT_ONLY_RENDERING = 2; static void drawLine(int[] canvas,int sx,int ex,int ny,int col) { for (int i=sx;i<=ex;i++) { Draw(canvas,i,ny,col); } } + public static void TexturedTriangle(int[] canvas, + int x1, int y1, float u1,float v1,float w1, + int x2, int y2, float u2,float v2,float w2, + int x3, int y3, float u3,float v3,float w3, + Texture texture, int colorMult,Triangle ref) { + TexturedTriangle(canvas,x1,y1,u1,v1,w1,x2,y2,u2,v2,w2,x3,y3,u3,v3,w3,texture,colorMult,ref,NORMAL_RENDERING); + } public static void TexturedTriangle(int[] canvas, int x1, int y1, float u1,float v1,float w1, int x2, int y2, float u2,float v2,float w2, int x3, int y3, float u3,float v3,float w3, - Texture texture, int colorMult,Triangle ref + Texture texture, int colorMult,Triangle ref, + int rendering_state ) { if (y2>>24)!=0) { - Draw(canvas,j,i,col); - } - if (((col&0xFF000000)>>>24)==255) { - SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; - SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + if (((col&0xFF000000)>>>24)!=255) { + if (rendering_state==TRANSLUCENT_ONLY_RENDERING|| + rendering_state==NORMAL_RENDERING) { + Draw(canvas,j,i,col); + SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; + SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + SigRenderer.translucencyBuffer[i*SigRenderer.SCREEN_WIDTH+j] = true; + } + } else { + if (rendering_state!=TRANSLUCENT_ONLY_RENDERING) { + Draw(canvas,j,i,col); + SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; + SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + } + } } } t+=tstep; @@ -147,11 +168,23 @@ public class DrawUtils { } int col = texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f); if (((col&0xFF000000)>>>24)!=0) { - Draw(canvas,j,i,col); - } - if (((col&0xFF000000)>>>24)==255) { - SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; - SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + if (((col&0xFF000000)>>>24)!=255) { + if (rendering_state==TRANSLUCENT_ONLY_RENDERING|| + rendering_state==NORMAL_RENDERING) { + Draw(canvas,j,i,col); + SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; + if (rendering_state!=TRANSLUCENT_ONLY_RENDERING) { + SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + } + SigRenderer.translucencyBuffer[i*SigRenderer.SCREEN_WIDTH+j] = true; + } + } else { + if (rendering_state!=TRANSLUCENT_ONLY_RENDERING) { + Draw(canvas,j,i,col); + SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; + SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; + } + } } } t+=tstep; @@ -350,7 +383,21 @@ public class DrawUtils { public static void Draw(int[] canvas,int x,int y,int col) { if (x>=0&&y>=0&&x>>24; + if (alpha>0&&alpha<255) { + float ratio = alpha/255f; + int prev_col = canvas[x+y*SigRenderer.SCREEN_WIDTH]; + int prev_r=(prev_col&0xFF),prev_g=(prev_col&0xFF00)>>>8,prev_b=(prev_col&0xFF0000)>>>16; + int r=(col&0xFF),g=(col&0xFF00)>>>8,b=(col&0xFF0000)>>>16; + + int new_r=(int)(ratio*r+(1-ratio)*prev_r); + int new_g=(int)(ratio*g+(1-ratio)*prev_g); + int new_b=(int)(ratio*b+(1-ratio)*prev_b); + + canvas[x+y*SigRenderer.SCREEN_WIDTH]=new_r+(new_g<<8)+(new_b<<16)+(col&0xFF000000); + } else { + canvas[x+y*SigRenderer.SCREEN_WIDTH]=col; + } } } } diff --git a/textures.png b/textures.png index 0f357de..622ea37 100644 Binary files a/textures.png and b/textures.png differ