Fixed Texture coordinates to account for perspective.

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
origin
sigonasr2, Sig, Sigo 3 years ago
parent 9ea6587bdf
commit 482d512433
  1. 25
      src/sig/Panel.java
  2. 12
      src/sig/SigRenderer.java
  3. 30
      src/sig/Texture.java
  4. 4
      src/sig/Triangle.java
  5. 2
      src/sig/Vector.java
  6. 10
      src/sig/Vector2.java
  7. 45
      src/sig/utils/DrawUtils.java

@ -17,6 +17,8 @@ import java.awt.GraphicsEnvironment;
import java.awt.GraphicsConfiguration;
import java.awt.Toolkit;
import sig.Texture;
public class Panel extends JPanel implements Runnable {
long startTime = System.nanoTime();
long endTime = System.nanoTime();
@ -149,9 +151,20 @@ public class Panel extends JPanel implements Runnable {
triProjected.B = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].B);
triProjected.C = Matrix.MultiplyVector(SigRenderer.matProj,clipped[i].C);
triProjected.col = clipped[i].col;
triProjected.T = clipped[i].T;
triProjected.U = clipped[i].U;
triProjected.V = clipped[i].V;
triProjected.T = (Vector2)clipped[i].T.clone();
triProjected.U = (Vector2)clipped[i].U.clone();
triProjected.V = (Vector2)clipped[i].V.clone();
triProjected.T.u = triProjected.T.u/triProjected.A.w;
triProjected.U.u = triProjected.U.u/triProjected.B.w;
triProjected.V.u = triProjected.V.u/triProjected.C.w;
triProjected.T.v = triProjected.T.v/triProjected.A.w;
triProjected.U.v = triProjected.U.v/triProjected.B.w;
triProjected.V.v = triProjected.V.v/triProjected.C.w;
triProjected.T.w = 1.0f/triProjected.A.w;
triProjected.U.w = 1.0f/triProjected.B.w;
triProjected.V.w = 1.0f/triProjected.C.w;
triProjected.A = Vector.divide(triProjected.A, triProjected.A.w);
triProjected.B = Vector.divide(triProjected.B, triProjected.B.w);
@ -215,9 +228,9 @@ public class Panel extends JPanel implements Runnable {
for (Triangle tt : triList) {
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,
(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.C.x,(int)tt.C.y,tt.V.u,tt.V.v,tt.V.w,
SigRenderer.dirtTex);
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);

@ -2,12 +2,9 @@ package sig;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import sig.utils.OBJReader;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.event.KeyEvent;
@ -45,7 +42,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
final float MOVESPEED = 0.03f;
final float TURNSPEED = 0.03f;
public static BufferedImage dirtTex;
public static Texture dirtTex;
boolean upHeld=false,downHeld=false,leftHeld=false,rightHeld=false,
aHeld=false,sHeld=false,dHeld=false,wHeld=false;
@ -81,12 +78,7 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
}
SigRenderer(JFrame f) {
try {
dirtTex = ImageIO.read(new File("dirt.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
dirtTex = new Texture(new File("dirt.png"));
//cube = new Mesh(OBJReader.ReadOBJFile("teapot.obj"));
cube = new Mesh(Arrays.asList(

@ -0,0 +1,30 @@
package sig;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.Color;
public class Texture{
BufferedImage tex;
public Texture(File f) {
try {
this.tex = ImageIO.read(f);
} catch (IOException e) {
e.printStackTrace();
}
}
public Color getColor(float u,float v) {
int sx = (int)(u*tex.getWidth()-1f);
int sy = (int)(v*tex.getHeight()-1f);
if (sx<0||sx>=tex.getWidth()||sy<0||sy>=tex.getHeight()) {
return new Color(0,0,0,0);
} else {
return new Color(tex.getRGB(sx,sy));
}
}
}

@ -90,9 +90,11 @@ public class Triangle {
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].U.w = t.t*(outside_tex[0].w-inside_tex[0].w)+inside_tex[0].w;
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;
out_tri[0].V.w = t.t*(outside_tex[1].w-inside_tex[0].w)+inside_tex[0].w;
return 1;
} else
if (insidePointCount==2&&outsidePointCount==1) {
@ -105,6 +107,7 @@ public class Triangle {
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[0].V.w = t.t*(outside_tex[0].w-inside_tex[0].w)+inside_tex[0].w;
out_tri[1].A = inside_points[1];
out_tri[1].T = inside_tex[1];
out_tri[1].B = out_tri[0].C;
@ -112,6 +115,7 @@ public class Triangle {
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;
out_tri[1].V.w = t.t*(outside_tex[0].w-inside_tex[1].w)+inside_tex[1].w;
return 2;
}

@ -16,7 +16,7 @@ public class Vector {
}
@Override
protected Object clone(){
return new Vector(x,y,z);
return new Vector(x,y,z,w);
}
public static Vector add(Vector v1,Vector v2) {

@ -1,16 +1,20 @@
package sig;
public class Vector2 {
public float u,v;
public float u,v,w;
Vector2() {
this(0,0);
this(0,0,1);
}
public Vector2(float u,float v) {
this(u,v,1);
}
public Vector2(float u,float v,float w) {
this.u=u;
this.v=v;
this.w=w;
}
@Override
protected Object clone(){
return new Vector2(u,v);
return new Vector2(u,v,w);
}
}

@ -5,6 +5,7 @@ import java.util.Arrays;
import java.awt.image.BufferedImage;
import sig.SigRenderer;
import sig.Texture;
public class DrawUtils {
static void drawLine(int[] canvas,int sx,int ex,int ny,Color col) {
@ -13,36 +14,40 @@ public class DrawUtils {
}
}
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
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
) {
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;}
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;float w=w1;w1=w2;w2=w;}
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;float w=w1;w1=w3;w3=w;}
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;float w=w2;w2=w3;w3=w;}
int dy1=y2-y1;
int dx1=x2-x1;
float dv1=v2-v1;
float du1=u2-u1;
float dw1=w2-w1;
int dy2=y3-y1;
int dx2=x3-x1;
float dv2=v3-v1;
float du2=u3-u1;
float tex_u,tex_v;
float dw2=w3-w1;
float tex_u,tex_v,tex_w;
float dax_step=0,dbx_step=0,
du1_step=0,dv1_step=0,
du2_step=0,dv2_step=0;
du1_step=0,dv1_step=0,dw1_step=0,
du2_step=0,dv2_step=0,dw2_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 (dy1!=0) {dw1_step=dw1/((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 (dy2!=0) {dw2_step=dw2/((float)Math.abs(dy2));}
if (dy1!=0) {
for (int i=y1;i<=y2;i++) {
@ -51,17 +56,21 @@ public class DrawUtils {
float tex_su=u1+((float)(i-y1))*du1_step;
float tex_sv=v1+((float)(i-y1))*dv1_step;
float tex_sw=w1+((float)(i-y1))*dw1_step;
float tex_eu=u1+((float)(i-y1))*du2_step;
float tex_ev=v1+((float)(i-y1))*dv2_step;
float tex_ew=w1+((float)(i-y1))*dw2_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;
float w=tex_sw;tex_sw=tex_ew;tex_ew=w;
}
tex_u=tex_su;
tex_v=tex_sv;
tex_w=tex_sw;
float tstep = 1.0f/((float)(bx-ax));
float t=0.0f;
@ -69,7 +78,8 @@ public class DrawUtils {
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)))));
tex_w=(1.0f-t)*tex_sw+t*tex_ew;
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w));
t+=tstep;
}
}
@ -79,31 +89,37 @@ public class DrawUtils {
dx1=x3-x2;
dv1=v3-v2;
du1=u3-u2;
dw1=w3-w2;
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) {dw1_step=dw1/((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);
int ax=(int)(x2+((float)(i-y2))*dax_step);
int bx=(int)(x1+((float)(i-y1))*dbx_step);
float tex_su=u2+((float)(i-y2))*du1_step;
float tex_sv=v2+((float)(i-y2))*dv1_step;
float tex_sw=w2+((float)(i-y2))*dw1_step;
float tex_eu=u1+((float)(i-y1))*du2_step;
float tex_ev=v1+((float)(i-y1))*dv2_step;
float tex_ew=w1+((float)(i-y1))*dw2_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;
float w=tex_sw;tex_sw=tex_ew;tex_ew=w;
}
tex_u=tex_su;
tex_v=tex_sv;
tex_w=tex_sw;
float tstep = 1.0f/((float)(bx-ax));
float t=0.0f;
@ -111,7 +127,8 @@ public class DrawUtils {
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)))));
tex_w=(1.0f-t)*tex_sw+t*tex_ew;
Draw(canvas,j,i,texture.getColor(tex_u/tex_w,tex_v/tex_w));
t+=tstep;
}
}

Loading…
Cancel
Save