Starting of texture mapping to 3D coords

origin
Joshua Sigona 3 years ago
parent edbd25ff2a
commit f70e1a4dbe
  1. BIN
      dirt.png
  2. 8
      src/sig/ExtraData.java
  3. 17
      src/sig/Panel.java
  4. 33
      src/sig/SigRenderer.java
  5. 40
      src/sig/Triangle.java
  6. 3
      src/sig/Vector.java
  7. 12
      src/sig/Vector2.java
  8. 106
      src/sig/utils/DrawUtils.java

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -0,0 +1,8 @@
package sig;
public class ExtraData {
public float t;
ExtraData(float t) {
this.t=t;
}
}

@ -109,6 +109,9 @@ public class Panel extends JPanel implements Runnable {
triTransformed.A = Matrix.MultiplyVector(matWorld,t.A); triTransformed.A = Matrix.MultiplyVector(matWorld,t.A);
triTransformed.B = Matrix.MultiplyVector(matWorld,t.B); triTransformed.B = Matrix.MultiplyVector(matWorld,t.B);
triTransformed.C = Matrix.MultiplyVector(matWorld,t.C); triTransformed.C = Matrix.MultiplyVector(matWorld,t.C);
triTransformed.T = t.T;
triTransformed.U = t.U;
triTransformed.V = t.V;
Vector normal=new Vector(),line1=new Vector(),line2=new Vector(); Vector normal=new Vector(),line1=new Vector(),line2=new Vector();
line1 = Vector.subtract(triTransformed.B,triTransformed.A); line1 = Vector.subtract(triTransformed.B,triTransformed.A);
@ -130,6 +133,9 @@ public class Panel extends JPanel implements Runnable {
triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B); triViewed.B = Matrix.MultiplyVector(matView,triTransformed.B);
triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C); triViewed.C = Matrix.MultiplyVector(matView,triTransformed.C);
triViewed.setColor(new Color(dp,dp,dp)); triViewed.setColor(new Color(dp,dp,dp));
triViewed.T = triTransformed.T;
triViewed.U = triTransformed.U;
triViewed.V = triTransformed.V;
int clippedTriangles = 0; int clippedTriangles = 0;
Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()}; Triangle[] clipped = new Triangle[]{new Triangle(),new Triangle()};
@ -143,6 +149,9 @@ public class Panel extends JPanel implements Runnable {
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B); triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B);
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C); triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
triProjected.col = clipped[i].col; triProjected.col = clipped[i].col;
triProjected.T = clipped[i].T;
triProjected.U = clipped[i].U;
triProjected.V = clipped[i].V;
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w); triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w); triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
@ -205,9 +214,13 @@ public class Panel extends JPanel implements Runnable {
} }
for (Triangle tt : triList) { for (Triangle tt : triList) {
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()); DrawUtils.TexturedTriangle(p,
(int)tt.A.x,(int)tt.A.y,tt.T.u,tt.T.v,
(int)tt.B.x,(int)tt.B.y,tt.U.u,tt.U.v,
(int)tt.C.x,(int)tt.C.y,tt.V.u,tt.V.v,
SigRenderer.dirtTex);
if (SigRenderer.WIREFRAME) { 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.BLACK); 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);
} }
} }
} }

@ -1,4 +1,5 @@
package sig; package sig;
import javax.imageio.ImageIO;
import javax.swing.JFrame; import javax.swing.JFrame;
import sig.utils.OBJReader; import sig.utils.OBJReader;
@ -6,15 +7,19 @@ 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;
import java.awt.image.BufferedImage;
import java.io.File;
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.Arrays;
import java.util.List; import java.util.List;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.BorderLayout; import java.awt.BorderLayout;
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
public static boolean WIREFRAME = false; public static boolean WIREFRAME = true;
public static Mesh cube; public static Mesh cube;
public static int SCREEN_WIDTH=1280; public static int SCREEN_WIDTH=1280;
@ -40,6 +45,8 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
final float MOVESPEED = 0.03f; final float MOVESPEED = 0.03f;
final float TURNSPEED = 0.03f; final float TURNSPEED = 0.03f;
public static BufferedImage dirtTex;
boolean upHeld=false,downHeld=false,leftHeld=false,rightHeld=false, boolean upHeld=false,downHeld=false,leftHeld=false,rightHeld=false,
aHeld=false,sHeld=false,dHeld=false,wHeld=false; aHeld=false,sHeld=false,dHeld=false,wHeld=false;
@ -74,7 +81,29 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
} }
SigRenderer(JFrame f) { SigRenderer(JFrame f) {
cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj"));
try {
dirtTex = ImageIO.read(new File("dirt.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
//cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj"));
cube = new Mesh(Arrays.asList(
new Triangle[]{
new Triangle(new Vector(),new Vector(0,1,0),new Vector(1,1,0),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(),new Vector(1,1,0),new Vector(1,0,0),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
new Triangle(new Vector(1,0,0),new Vector(1,1,0),new Vector(1,1,1),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(1,0,0),new Vector(1,1,1),new Vector(1,0,1),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
new Triangle(new Vector(1,0,1),new Vector(1,1,1),new Vector(0,1,1),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(1,0,1),new Vector(0,1,1),new Vector(0,0,1),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
new Triangle(new Vector(0,0,1),new Vector(0,1,1),new Vector(0,1,0),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(0,0,1),new Vector(0,1,0),new Vector(0,0,0),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
new Triangle(new Vector(0,1,0),new Vector(0,1,1),new Vector(1,1,1),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(0,1,0),new Vector(1,1,1),new Vector(1,1,0),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
new Triangle(new Vector(1,0,1),new Vector(0,0,1),new Vector(0,0,0),new Vector2(0,1),new Vector2(0,0),new Vector2(1,0)),
new Triangle(new Vector(1,0,1),new Vector(0,0,0),new Vector(1,0,0),new Vector2(0,1),new Vector2(1,0),new Vector2(1,1)),
}));
Panel p = new Panel(); Panel p = new Panel();

@ -1,17 +1,23 @@
package sig; package sig;
import java.awt.Color; import java.awt.Color;
import java.util.Arrays;
public class Triangle { public class Triangle {
Vector A,B,C; Vector A,B,C;
Vector2 T,U,V;
Color col = Color.WHITE; Color col = Color.WHITE;
public Triangle() { public Triangle() {
this(new Vector(),new Vector(),new Vector()); this(new Vector(),new Vector(),new Vector());
} }
public Triangle(Vector A,Vector B,Vector C) { public Triangle(Vector A,Vector B,Vector C) {
this(A,B,C,new Vector2(),new Vector2(),new Vector2());
}
public Triangle(Vector A,Vector B,Vector C,Vector2 T,Vector2 U,Vector2 V) {
this.A=A; this.A=A;
this.B=B; this.B=B;
this.C=C; this.C=C;
this.T=T;
this.U=U;
this.V=V;
} }
@Override @Override
protected Object clone(){ protected Object clone(){
@ -38,7 +44,10 @@ public class Triangle {
plane_n = Vector.normalize(plane_n); plane_n = Vector.normalize(plane_n);
Vector[] inside_points = new Vector[]{new Vector(),new Vector(),new Vector()}; Vector[] inside_points = new Vector[]{new Vector(),new Vector(),new Vector()};
Vector[] outside_points = new Vector[]{new Vector(),new Vector(),new Vector()}; Vector[] outside_points = new Vector[]{new Vector(),new Vector(),new Vector()};
Vector2[] inside_tex = new Vector2[]{new Vector2(),new Vector2(),new Vector2()};
Vector2[] outside_tex = new Vector2[]{new Vector2(),new Vector2(),new Vector2()};
int insidePointCount=0,outsidePointCount=0; int insidePointCount=0,outsidePointCount=0;
int insideTexCount=0,outsideTexCount=0;
float d0=dist(plane_p,plane_n,in.A); float d0=dist(plane_p,plane_n,in.A);
float d1=dist(plane_p,plane_n,in.B); float d1=dist(plane_p,plane_n,in.B);
@ -46,18 +55,24 @@ public class Triangle {
if (d0>=0) { if (d0>=0) {
inside_points[insidePointCount++]=in.A; inside_points[insidePointCount++]=in.A;
inside_tex[insideTexCount++]=in.T;
} else { } else {
outside_points[outsidePointCount++]=in.A; outside_points[outsidePointCount++]=in.A;
outside_tex[outsideTexCount++]=in.T;
} }
if (d1>=0) { if (d1>=0) {
inside_points[insidePointCount++]=in.B; inside_points[insidePointCount++]=in.B;
inside_tex[insideTexCount++]=in.U;
} else { } else {
outside_points[outsidePointCount++]=in.B; outside_points[outsidePointCount++]=in.B;
outside_tex[outsideTexCount++]=in.U;
} }
if (d2>=0) { if (d2>=0) {
inside_points[insidePointCount++]=in.C; inside_points[insidePointCount++]=in.C;
inside_tex[insideTexCount++]=in.V;
} else { } else {
outside_points[outsidePointCount++]=in.C; outside_points[outsidePointCount++]=in.C;
outside_tex[outsideTexCount++]=in.V;
} }
if (insidePointCount==0) { if (insidePointCount==0) {
@ -68,20 +83,35 @@ public class Triangle {
return 1; return 1;
} else } else
if (insidePointCount==1&&outsidePointCount==2) { if (insidePointCount==1&&outsidePointCount==2) {
ExtraData t = new ExtraData(0);
out_tri[0].col = in.col; out_tri[0].col = in.col;
out_tri[0].A = inside_points[0]; out_tri[0].A = inside_points[0];
out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0]); out_tri[0].T = inside_tex[0];
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[1]); out_tri[0].B = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0],t);
out_tri[0].U.u = t.t*(outside_tex[0].u-inside_tex[0].u)+inside_tex[0].u;
out_tri[0].U.v = t.t*(outside_tex[0].v-inside_tex[0].v)+inside_tex[0].v;
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[1],t);
out_tri[0].V.u = t.t*(outside_tex[1].u-inside_tex[0].u)+inside_tex[0].u;
out_tri[0].V.v = t.t*(outside_tex[1].v-inside_tex[0].v)+inside_tex[0].v;
return 1; return 1;
} else } else
if (insidePointCount==2&&outsidePointCount==1) { if (insidePointCount==2&&outsidePointCount==1) {
ExtraData t = new ExtraData(0);
out_tri[0].col=out_tri[1].col=in.col; out_tri[0].col=out_tri[1].col=in.col;
out_tri[0].A = inside_points[0]; out_tri[0].A = inside_points[0];
out_tri[0].B = inside_points[1]; out_tri[0].B = inside_points[1];
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0]); out_tri[0].T = inside_tex[0];
out_tri[0].U = inside_tex[1];
out_tri[0].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[0], outside_points[0],t);
out_tri[0].V.u = t.t*(outside_tex[0].u-inside_tex[0].u)+inside_tex[0].u;
out_tri[0].V.v = t.t*(outside_tex[0].v-inside_tex[0].v)+inside_tex[0].v;
out_tri[1].A = inside_points[1]; out_tri[1].A = inside_points[1];
out_tri[1].T = inside_tex[1];
out_tri[1].B = out_tri[0].C; out_tri[1].B = out_tri[0].C;
out_tri[1].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[1], outside_points[0]); out_tri[1].U = out_tri[0].V;
out_tri[1].C = Vector.IntersectPlane(plane_p, plane_n, inside_points[1], outside_points[0],t);
out_tri[1].V.u = t.t*(outside_tex[0].u-inside_tex[1].u)+inside_tex[1].u;
out_tri[1].V.v = t.t*(outside_tex[0].v-inside_tex[1].v)+inside_tex[1].v;
return 2; return 2;
} }

@ -53,12 +53,13 @@ public class Vector {
public String toString() { public String toString() {
return "Vector ["+x+","+y+","+z+","+w+"]"; return "Vector ["+x+","+y+","+z+","+w+"]";
} }
public static Vector IntersectPlane(Vector plane_p,Vector plane_n,Vector lineStart,Vector lineEnd) { public static Vector IntersectPlane(Vector plane_p,Vector plane_n,Vector lineStart,Vector lineEnd,ExtraData tt) {
plane_n = Vector.normalize(plane_n); plane_n = Vector.normalize(plane_n);
float plane_d = -Vector.dotProduct(plane_n,plane_p); float plane_d = -Vector.dotProduct(plane_n,plane_p);
float ad = Vector.dotProduct(lineStart,plane_n); float ad = Vector.dotProduct(lineStart,plane_n);
float bd = Vector.dotProduct(lineEnd,plane_n); float bd = Vector.dotProduct(lineEnd,plane_n);
float t = (-plane_d-ad)/(bd-ad); float t = (-plane_d-ad)/(bd-ad);
tt.t=t;
Vector lineStartToEnd = Vector.subtract(lineEnd,lineStart); Vector lineStartToEnd = Vector.subtract(lineEnd,lineStart);
Vector lineToIntersect = Vector.multiply(lineStartToEnd,t); Vector lineToIntersect = Vector.multiply(lineStartToEnd,t);
return Vector.add(lineStart,lineToIntersect); return Vector.add(lineStart,lineToIntersect);

@ -0,0 +1,12 @@
package sig;
public class Vector2 {
public float u,v;
Vector2() {
this(0,0);
}
public Vector2(float u,float v) {
this.u=u;
this.v=v;
}
}

@ -2,6 +2,7 @@ package sig.utils;
import java.awt.Color; import java.awt.Color;
import java.util.Arrays; import java.util.Arrays;
import java.awt.image.BufferedImage;
import sig.SigRenderer; import sig.SigRenderer;
@ -11,6 +12,111 @@ public class DrawUtils {
Draw(canvas,i,ny,col); Draw(canvas,i,ny,col);
} }
} }
public static void TexturedTriangle(int[] canvas,
int x1, int y1, float u1,float v1,
int x2, int y2, float u2,float v2,
int x3, int y3, float u3,float v3,
BufferedImage texture
) {
if (y2<y1) {int t=y1;y1=y2;y2=t;t=x1;x1=x2;x2=t;float u=u1;u1=u2;u2=u;float v=v1;v1=v2;v2=v;}
if (y3<y1) {int t=y1;y1=y3;y3=t;t=x1;x1=x3;x3=t;float u=u1;u1=u3;u3=u;float v=v1;v1=v3;v3=v;}
if (y3<y2) {int t=y2;y2=y3;y3=t;t=x2;x2=x3;x3=t;float u=u2;u2=u3;u3=u;float v=v2;v2=v3;v3=v;}
int dy1=y2-y1;
int dx1=x2-x1;
float dv1=v2-v1;
float du1=u2-u1;
int dy2=y3-y1;
int dx2=x3-x1;
float dv2=v3-v1;
float du2=u3-u1;
float tex_u,tex_v;
float dax_step=0,dbx_step=0,
du1_step=0,dv1_step=0,
du2_step=0,dv2_step=0;
if (dy1!=0) {dax_step=dx1/(float)Math.abs(dy1);}
if (dy2!=0) {dbx_step=dx2/(float)Math.abs(dy2);}
if (dy1!=0) {du1_step=du1/(float)Math.abs(dy1);}
if (dy1!=0) {dv1_step=dv1/(float)Math.abs(dy1);}
if (dy2!=0) {du2_step=du2/(float)Math.abs(dy2);}
if (dy2!=0) {dv2_step=dv2/(float)Math.abs(dy2);}
if (dy1!=0) {
for (int i=y1;i<=y2;i++) {
int ax=(int)(x1+(float)(i-y1)*dax_step);
int bx=(int)(x1+(float)(i-y1)*dbx_step);
float tex_su=(int)(u1+(float)(i-y1)*du1_step);
float tex_sv=(int)(v1+(float)(i-y1)*dv1_step);
float tex_eu=(int)(u1+(float)(i-y1)*du2_step);
float tex_ev=(int)(v1+(float)(i-y1)*dv2_step);
if (ax>bx) {
int t=ax;ax=bx;bx=t;
float u=tex_su;tex_su=tex_eu;tex_eu=u;
float v=tex_sv;tex_sv=tex_ev;tex_ev=v;
}
tex_u=tex_su;
tex_v=tex_sv;
float tstep = 1.0f/((float)(bx-ax));
float t=0.0f;
for (int j=ax;j<bx;j++) {
tex_u=(1.0f-t)*tex_su+t*tex_eu;
tex_v=(1.0f-t)*tex_sv+t*tex_ev;
Draw(canvas,j,i,new Color(texture.getRGB((int)Math.max(0,tex_u*(texture.getWidth()-1)),(int)Math.max(0,tex_v*(texture.getHeight()-1)))));
t+=tstep;
}
}
}
dy1=y3-y2;
dx1=x3-x2;
dv1=v3-v2;
du1=u3-u2;
if (dy1!=0) {dax_step=dx1/(float)Math.abs(dy1);}
if (dy2!=0) {dbx_step=dx2/(float)Math.abs(dy2);}
du1_step=0f;
dv1_step=0f;
if (dy1!=0) {du1_step=du1/(float)Math.abs(dy1);}
if (dy1!=0) {dv1_step=dv1/(float)Math.abs(dy1);}
if (dy1!=0) {
for (int i=y2;i<=y3;i++) {
int ax=(int)(x2+(float)(i-y2)*dax_step);
int bx=(int)(x1+(float)(i-y1)*dbx_step);
float tex_su=(int)(u2+(float)(i-y2)*du1_step);
float tex_sv=(int)(v2+(float)(i-y2)*dv1_step);
float tex_eu=(int)(u1+(float)(i-y1)*du2_step);
float tex_ev=(int)(v1+(float)(i-y1)*dv2_step);
if (ax>bx) {
int t=ax;ax=bx;bx=t;
float u=tex_su;tex_su=tex_eu;tex_eu=u;
float v=tex_sv;tex_sv=tex_ev;tex_ev=v;
}
tex_u=tex_su;
tex_v=tex_sv;
float tstep = 1.0f/((float)(bx-ax));
float t=0.0f;
for (int j=ax;j<bx;j++) {
tex_u=(1.0f-t)*tex_su+t*tex_eu;
tex_v=(1.0f-t)*tex_sv+t*tex_ev;
Draw(canvas,j,i,new Color(texture.getRGB((int)Math.max(0,tex_u*(texture.getWidth()-1)),(int)Math.max(0,tex_v*(texture.getHeight()-1)))));
t+=tstep;
}
}
}
}
public static void FillTriangle(int[] canvas,int x1, int y1, int x2, int y2, int x3, int y3, Color col) public static void FillTriangle(int[] canvas,int x1, int y1, int x2, int y2, int x3, int y3, Color col)
{ {
int t1x=0, t2x=0, y=0, minx=0, maxx=0, t1xp=0, t2xp=0; int t1x=0, t2x=0, y=0, minx=0, maxx=0, t1xp=0, t2xp=0;

Loading…
Cancel
Save