Transparent texture rendering handling.

origin
Joshua Sigona 3 years ago
parent 057ef44afb
commit 5d6c8de3b5
  1. BIN
      SigRenderer-0-jar-with-dependencies.jar
  2. 24
      cube.obj
  3. 6
      pom.xml
  4. 42
      src/sig/Block.java
  5. 24
      src/sig/Panel.java
  6. 30
      src/sig/SigRenderer.java
  7. 10
      src/sig/Texture.java
  8. 1
      src/sig/Triangle.java
  9. 22
      src/sig/utils/DrawUtils.java

@ -12,15 +12,15 @@ vt 0 1 #2
vt 1 0 #3 vt 1 0 #3
vt 1 1 #4 vt 1 1 #4
f 1/2 3/1 7/3 #South f 1/2 3/1 7/3 #South/0
f 1/2 7/3 5/4 f 1/2 7/3 5/4 #1
f 5/2 7/1 8/3 #East f 5/2 7/1 8/3 #East/2
f 5/2 8/3 6/4 f 5/2 8/3 6/4 #3
f 6/2 8/1 4/3 #North f 6/2 8/1 4/3 #North/4
f 6/2 4/3 2/4 f 6/2 4/3 2/4 #5
f 2/2 4/1 3/3 #West f 2/2 4/1 3/3 #West/6
f 2/2 3/3 1/4 f 2/2 3/3 1/4 #7
f 3/2 4/1 8/3 #Top f 3/2 4/1 8/3 #Top/8
f 3/2 8/3 7/4 f 3/2 8/3 7/4 #9
f 6/2 2/1 1/3 #Bottom f 6/2 2/1 1/3 #Bottom/10
f 6/2 1/3 5/4 f 6/2 1/3 5/4 #11

@ -17,12 +17,6 @@
</properties> </properties>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/org.jogamp.jogl/jogl-all-main -->
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -21,27 +21,57 @@ public class Block {
public void updateFaces() { public void updateFaces() {
if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y+1)+"_"+pos.z)) { if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y+1)+"_"+pos.z)) {
neighbors.UP=true; neighbors.UP=true;
SigRenderer.blockGrid.get(pos.x+"_"+(pos.y+1)+"_"+pos.z).neighbors.DOWN=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;
}
} }
if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y-1)+"_"+pos.z)) { if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y-1)+"_"+pos.z)) {
neighbors.DOWN=true; neighbors.DOWN=true;
SigRenderer.blockGrid.get(pos.x+"_"+(pos.y-1)+"_"+pos.z).neighbors.UP=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;
}
} }
if (SigRenderer.blockGrid.containsKey((pos.x-1)+"_"+(pos.y)+"_"+pos.z)) { if (SigRenderer.blockGrid.containsKey((pos.x-1)+"_"+(pos.y)+"_"+pos.z)) {
neighbors.LEFT=true; neighbors.LEFT=true;
SigRenderer.blockGrid.get((pos.x-1)+"_"+(pos.y)+"_"+pos.z).neighbors.RIGHT=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;
}
} }
if (SigRenderer.blockGrid.containsKey((pos.x+1)+"_"+(pos.y)+"_"+pos.z)) { if (SigRenderer.blockGrid.containsKey((pos.x+1)+"_"+(pos.y)+"_"+pos.z)) {
neighbors.RIGHT=true; neighbors.RIGHT=true;
SigRenderer.blockGrid.get((pos.x+1)+"_"+(pos.y)+"_"+pos.z).neighbors.LEFT=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;
}
} }
if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z+1))) { if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z+1))) {
neighbors.FORWARD=true; neighbors.FORWARD=true;
SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z+1)).neighbors.BACKWARD=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;
}
} }
if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z-1))) { if (SigRenderer.blockGrid.containsKey(pos.x+"_"+(pos.y)+"_"+(pos.z-1))) {
neighbors.BACKWARD=true; neighbors.BACKWARD=true;
SigRenderer.blockGrid.get(pos.x+"_"+(pos.y)+"_"+(pos.z-1)).neighbors.FORWARD=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;
}
} }
} }
@Override @Override

@ -9,6 +9,7 @@ import java.awt.Color;
import java.awt.Image; import java.awt.Image;
import java.awt.image.MemoryImageSource; import java.awt.image.MemoryImageSource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@ -176,7 +177,12 @@ public class Panel extends JPanel implements Runnable {
SigRenderer.tempAnswer=null; SigRenderer.tempAnswer=null;
long totalTime=0; long totalTime=0;
long startTime2=0; long startTime2=0;
ConcurrentLinkedQueue<Triangle> currentRender = (renderFirst)?accumulatedTris1:accumulatedTris2; Collection<Triangle> currentRender = (renderFirst)?accumulatedTris1:accumulatedTris2;
List<Triangle> newTris = new ArrayList<>();
for (Triangle t:currentRender) {
prepareTriForRender(matWorld, matView, t.unmodifiedTri, newTris, true);
}
currentRender=newTris;
for (Triangle t : currentRender) { for (Triangle t : currentRender) {
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()};
List<Triangle> triList = new ArrayList<>(); List<Triangle> triList = new ArrayList<>();
@ -206,7 +212,11 @@ public class Panel extends JPanel implements Runnable {
} }
for (Triangle tt : triList) { for (Triangle tt : triList) {
if (tt.tex!=null) { if (tt.tex!=null) {
//tt.unmodifiedTri.nextRenderTime=System.currentTimeMillis()+200; if (renderFirst) {
tt.unmodifiedTri.nextRenderTime=System.currentTimeMillis()+200;
} else {
tt.unmodifiedTri.nextRenderTime2=System.currentTimeMillis()+200;
}
DrawUtils.TexturedTriangle(p, DrawUtils.TexturedTriangle(p,
(int)tt.A.x,(int)tt.A.y,tt.T.u,tt.T.v,tt.T.w, (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, (int)tt.B.x,(int)tt.B.y,tt.U.u,tt.U.v,tt.U.w,
@ -228,7 +238,7 @@ public class Panel extends JPanel implements Runnable {
for (int y=0;y<SigRenderer.SCREEN_HEIGHT;y++) { for (int y=0;y<SigRenderer.SCREEN_HEIGHT;y++) {
Triangle t = SigRenderer.depthBuffer_tri[x+y*SigRenderer.SCREEN_WIDTH]; Triangle t = SigRenderer.depthBuffer_tri[x+y*SigRenderer.SCREEN_WIDTH];
if (t!=null) { if (t!=null) {
t.nextRenderTime=-1; t.nextRenderTime=t.nextRenderTime2=-1;
} }
} }
} }
@ -239,8 +249,12 @@ public class Panel extends JPanel implements Runnable {
} }
} }
private void prepareTriForRender(Matrix matWorld, Matrix matView, Triangle t, ConcurrentLinkedQueue<Triangle> accumulatedTris) { private void prepareTriForRender(Matrix matWorld, Matrix matView, Triangle t, Collection<Triangle> accumulatedTris) {
if (t.nextRenderTime<=System.currentTimeMillis()) { prepareTriForRender(matWorld,matView,t,accumulatedTris,false);
}
private void prepareTriForRender(Matrix matWorld, Matrix matView, Triangle t, Collection<Triangle> accumulatedTris, boolean buffer) {
if (!buffer||(buffer&&t.nextRenderTime<=System.currentTimeMillis())) {
Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle(); Triangle triProjected = new Triangle(),triTransformed=new Triangle(),triViewed=new Triangle();
if (t.b!=null) { if (t.b!=null) {

@ -2,8 +2,6 @@ package sig;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.JFrame; import javax.swing.JFrame;
import sig.utils.OBJReader;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
@ -13,14 +11,10 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.BorderLayout; import java.awt.BorderLayout;
@ -110,13 +104,21 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
SigRenderer(JFrame f) { SigRenderer(JFrame f) {
//cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false)); //cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj",false));
Random r = new Random(438107); Random r = new Random(438107);
for (int x=0;x<256;x++) { for (int x=0;x<64;x++) {
for (int z=0;z<256;z++) { for (int z=0;z<64;z++) {
addBlock(new Vector(x,0,z),BlockType.DIRT);
/*
if (Math.random()<=0.5) { if (Math.random()<=0.5) {
addBlock(new Vector(x,0,z),BlockType.DIRT); addBlock(new Vector(x,y,z),BlockType.GLASS);
} else { } else {
addBlock(new Vector(x,0,z),BlockType.SNOW_DIRT); addBlock(new Vector(x,y,z),BlockType.SNOW_DIRT);
} }*/
}
}
for (int x=0;x<64;x++) {
for (int y=0;y<5;y++) {
addBlock(new Vector(x,y,16),BlockType.GLASS);
} }
} }
@ -169,15 +171,19 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
WritableRaster r = img.getRaster(); WritableRaster r = img.getRaster();
for (TextureType tt : TextureType.values()) { for (TextureType tt : TextureType.values()) {
int[] pixelData = new int[tt.texWidth*BLOCK_WIDTH*tt.texHeight*BLOCK_HEIGHT]; 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);
int startX=tt.texX*BLOCK_WIDTH; int startX=tt.texX*BLOCK_WIDTH;
int startY=tt.texY*BLOCK_HEIGHT; int startY=tt.texY*BLOCK_HEIGHT;
for (int x=0;x<tt.texWidth*BLOCK_WIDTH;x++) { for (int x=0;x<tt.texWidth*BLOCK_WIDTH;x++) {
for (int y=0;y<tt.texHeight*BLOCK_HEIGHT;y++) { for (int y=0;y<tt.texHeight*BLOCK_HEIGHT;y++) {
int[] pixel = r.getPixel(x+startX,y+startY,new int[4]); int[] pixel = r.getPixel(x+startX,y+startY,new int[4]);
pixelData[x+y*tt.texWidth*BLOCK_WIDTH]=pixel[2]+(pixel[1]<<8)+(pixel[0]<<16)+(pixel[3]<<24); pixelData[x+y*tt.texWidth*BLOCK_WIDTH]=pixel[2]+(pixel[1]<<8)+(pixel[0]<<16)+(pixel[3]<<24);
if (pixel[3]<255) {
tex.hasTransparency=true;
}
} }
} }
blockTextures.put(tt,new Texture(pixelData,tt.texWidth*BLOCK_WIDTH,tt.texHeight*BLOCK_HEIGHT)); blockTextures.put(tt,tex);
} }
JFrame f = new JFrame("SigRenderer"); JFrame f = new JFrame("SigRenderer");

@ -13,6 +13,7 @@ public class Texture{
int[] tex; int[] tex;
int width; int width;
int height; int height;
public boolean hasTransparency=false;
public Texture(File f) { public Texture(File f) {
try { try {
@ -33,6 +34,13 @@ public class Texture{
} }
} }
public static final int SOUTH = 0;
public static final int EAST = 2;
public static final int NORTH = 4;
public static final int WEST = 6;
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) {
this.tex=tex; this.tex=tex;
this.width=width; this.width=width;
@ -47,7 +55,7 @@ public class Texture{
} else { } else {
int indice = (int)(u*width-1)+(int)(v*height-1)*width; int indice = (int)(u*width-1)+(int)(v*height-1)*width;
//return tex[indice]; //return tex[indice];
return (int)((tex[indice]&0xFF)*mult) + ((int)(((tex[indice]&0xFF00)>>8)*mult)<<8) + ((int)(((tex[indice]&0xFF0000)>>16)*mult)<<16); return (int)((tex[indice]&0xFF)*mult) + ((int)(((tex[indice]&0xFF00)>>>8)*mult)<<8) + ((int)(((tex[indice]&0xFF0000)>>>16)*mult)<<16) + ((((tex[indice]&0xFF000000)>>>24))<<24);
/*Color newCol = new Color(tex.getRGB(sx,sy)); /*Color newCol = new Color(tex.getRGB(sx,sy));
return new Color((newCol.getRed()/255f)*mult,(newCol.getGreen()/255f)*mult,(newCol.getBlue()/255f)*mult);*/ return new Color((newCol.getRed()/255f)*mult,(newCol.getGreen()/255f)*mult,(newCol.getBlue()/255f)*mult);*/
} }

@ -8,6 +8,7 @@ public class Triangle {
public Block b = null; public Block b = null;
public Texture tex = null; public Texture tex = null;
public long nextRenderTime = -1l; public long nextRenderTime = -1l;
public long nextRenderTime2 = -1l;
public Triangle unmodifiedTri; public Triangle unmodifiedTri;
public Triangle() { public Triangle() {
this(new Vector(),new Vector(),new Vector()); this(new Vector(),new Vector(),new Vector());

@ -84,9 +84,14 @@ public class DrawUtils {
if (SigRenderer.request!=null&&j==SigRenderer.request.getX()&&i==SigRenderer.request.getY()) { if (SigRenderer.request!=null&&j==SigRenderer.request.getX()&&i==SigRenderer.request.getY()) {
SigRenderer.tempAnswer=ref.b; SigRenderer.tempAnswer=ref.b;
} }
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f)); int col = texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f);
SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; if (((col&0xFF000000)>>>24)!=0) {
SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; 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;
}
} }
t+=tstep; t+=tstep;
} }
@ -140,9 +145,14 @@ public class DrawUtils {
if (SigRenderer.request!=null&&j==SigRenderer.request.getX()&&i==SigRenderer.request.getY()) { if (SigRenderer.request!=null&&j==SigRenderer.request.getX()&&i==SigRenderer.request.getY()) {
SigRenderer.tempAnswer=ref.b; SigRenderer.tempAnswer=ref.b;
} }
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f)); int col = texture.getColor(tex_u/tex_w,tex_v/tex_w,colorMult/255f);
SigRenderer.depthBuffer[i*SigRenderer.SCREEN_WIDTH+j] = tex_w; if (((col&0xFF000000)>>>24)!=0) {
SigRenderer.depthBuffer_tri[i*SigRenderer.SCREEN_WIDTH+j] = ref.unmodifiedTri; 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;
}
} }
t+=tstep; t+=tstep;
} }

Loading…
Cancel
Save