Draw a rotating 3D cube.
This commit is contained in:
parent
0bb1e490c3
commit
9e324be3e2
23
src/sig/Matrix.java
Normal file
23
src/sig/Matrix.java
Normal file
@ -0,0 +1,23 @@
|
||||
package sig;
|
||||
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
public class Matrix {
|
||||
float[][] m = new float[4][4];
|
||||
Matrix(float[][]m) {
|
||||
this.m=m;
|
||||
}
|
||||
|
||||
public static void MultiplyMatrixVector(Vector3f i,Vector3f o,Matrix m) {
|
||||
o.x=i.x*m.m[0][0]+i.y*m.m[1][0]+i.z*m.m[2][0]+m.m[3][0];
|
||||
o.y=i.x*m.m[0][1]+i.y*m.m[1][1]+i.z*m.m[2][1]+m.m[3][1];
|
||||
o.z=i.x*m.m[0][2]+i.y*m.m[1][2]+i.z*m.m[2][2]+m.m[3][2];
|
||||
float w=i.x*m.m[0][3]+i.y*m.m[1][3]+i.z*m.m[2][3]+m.m[3][3];
|
||||
|
||||
if (w!=0f) {
|
||||
o.x/=w;
|
||||
o.y/=w;
|
||||
o.z/=w;
|
||||
}
|
||||
}
|
||||
}
|
11
src/sig/Mesh.java
Normal file
11
src/sig/Mesh.java
Normal file
@ -0,0 +1,11 @@
|
||||
package sig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Mesh {
|
||||
List<Triangle> triangles = new ArrayList<>();
|
||||
Mesh(List<Triangle> tris) {
|
||||
this.triangles=tris;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package sig;
|
||||
import javax.swing.JPanel;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import sig.utils.DrawUtils;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Color;
|
||||
|
||||
@ -22,6 +24,7 @@ public class Panel extends JPanel implements Runnable {
|
||||
private MemoryImageSource mImageProducer;
|
||||
private ColorModel cm;
|
||||
private Thread thread;
|
||||
float fTheta=0f;
|
||||
|
||||
public Panel() {
|
||||
super(true);
|
||||
@ -46,6 +49,8 @@ public class Panel extends JPanel implements Runnable {
|
||||
cm = getCompatibleColorModel();
|
||||
width = getWidth();
|
||||
height = getHeight();
|
||||
SigRenderer.SCREEN_WIDTH=getWidth();
|
||||
SigRenderer.SCREEN_HEIGHT=getHeight();
|
||||
int screenSize = width * height;
|
||||
if(pixel == null || pixel.length < screenSize){
|
||||
pixel = new int[screenSize];
|
||||
@ -64,6 +69,7 @@ public class Panel extends JPanel implements Runnable {
|
||||
*/
|
||||
public /* abstract */ void render(){
|
||||
int[] p = pixel; // this avoid crash when resizing
|
||||
//a=h/w
|
||||
|
||||
final int h=SigRenderer.SCREEN_HEIGHT;
|
||||
if(p.length != width * height) return;
|
||||
@ -75,6 +81,56 @@ public class Panel extends JPanel implements Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix matRotZ = new Matrix(new float[][]{
|
||||
{(float)Math.cos(fTheta),(float)Math.sin(fTheta),0,0,},
|
||||
{(float)-Math.sin(fTheta),(float)Math.cos(fTheta),0,0,},
|
||||
{0,0,1,0,},
|
||||
{0,0,0,1,},
|
||||
}),matRotX = new Matrix(new float[][]{
|
||||
{1,0,0,0,},
|
||||
{0,(float)Math.cos(fTheta*0.5f),(float)Math.sin(fTheta*0.5f),0,},
|
||||
{0,(float)-Math.sin(fTheta*0.5f),(float)Math.cos(fTheta*0.5f),0,},
|
||||
{0,0,0,1,},
|
||||
});
|
||||
fTheta+=0.01f;
|
||||
|
||||
for (Triangle t : SigRenderer.cube.triangles) {
|
||||
Triangle triProjected = new Triangle(new Vector3f(),new Vector3f(),new Vector3f()),triTranslated=new Triangle(new Vector3f(),new Vector3f(),new Vector3f()),triRotatedZ=new Triangle(new Vector3f(),new Vector3f(),new Vector3f()),triRotatedZX=new Triangle(new Vector3f(),new Vector3f(),new Vector3f());
|
||||
|
||||
|
||||
Matrix.MultiplyMatrixVector(t.A, triRotatedZ.A, matRotZ);
|
||||
Matrix.MultiplyMatrixVector(t.B, triRotatedZ.B, matRotZ);
|
||||
Matrix.MultiplyMatrixVector(t.C, triRotatedZ.C, matRotZ);
|
||||
Matrix.MultiplyMatrixVector(triRotatedZ.A, triRotatedZX.A, matRotX);
|
||||
Matrix.MultiplyMatrixVector(triRotatedZ.B, triRotatedZX.B, matRotX);
|
||||
Matrix.MultiplyMatrixVector(triRotatedZ.C, triRotatedZX.C, matRotX);
|
||||
|
||||
|
||||
triTranslated = (Triangle)triRotatedZX.clone();
|
||||
triTranslated.A.z=triRotatedZX.A.z+3f;
|
||||
triTranslated.B.z=triRotatedZX.B.z+3f;
|
||||
triTranslated.C.z=triRotatedZX.C.z+3f;
|
||||
|
||||
Matrix.MultiplyMatrixVector(triTranslated.A, triProjected.A, SigRenderer.matProj);
|
||||
Matrix.MultiplyMatrixVector(triTranslated.B, triProjected.B, SigRenderer.matProj);
|
||||
Matrix.MultiplyMatrixVector(triTranslated.C, triProjected.C, SigRenderer.matProj);
|
||||
|
||||
triProjected.A.x+=1f;
|
||||
triProjected.A.y+=1f;
|
||||
triProjected.B.x+=1f;
|
||||
triProjected.B.y+=1f;
|
||||
triProjected.C.x+=1f;
|
||||
triProjected.C.y+=1f;
|
||||
triProjected.A.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||
triProjected.A.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||
triProjected.B.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||
triProjected.B.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||
triProjected.C.x*=0.5f*SigRenderer.SCREEN_WIDTH;
|
||||
triProjected.C.y*=0.5f*SigRenderer.SCREEN_HEIGHT;
|
||||
|
||||
DrawUtils.DrawTriangle(p,(int)triProjected.A.x,(int)triProjected.A.y,(int)triProjected.B.x,(int)triProjected.B.y,(int)triProjected.C.x,(int)triProjected.C.y,Color.BLACK);
|
||||
}
|
||||
i += 1;
|
||||
j += 1;
|
||||
endTime=System.nanoTime();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package sig;
|
||||
import javax.swing.JFrame;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Point2d;
|
||||
import javax.vecmath.Tuple3d;
|
||||
import javax.vecmath.Vector3f;
|
||||
@ -9,14 +10,17 @@ import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
||||
public static Triangle tri,tri2,tri3,tri4,tri5,tri6;
|
||||
public final static int SCREEN_WIDTH=1280;
|
||||
public final static int SCREEN_HEIGHT=720;
|
||||
public static Mesh cube;
|
||||
public static int SCREEN_WIDTH=1280;
|
||||
public static int SCREEN_HEIGHT=720;
|
||||
public final static long TIMEPERTICK = 16666667l;
|
||||
public static float DRAWTIME=0;
|
||||
public static float DRAWLOOPTIME=0;
|
||||
@ -27,21 +31,52 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
||||
|
||||
public static List<Pixel> pixels;
|
||||
|
||||
public static float fNear = 0.1f;
|
||||
public static float fFar = 1000f;
|
||||
public static float fFov = 90f;
|
||||
public static float fAspectRatio = (float)SCREEN_HEIGHT/SCREEN_WIDTH;
|
||||
public static float fFovRad = 1f/(float)Math.tan(fFov*0.5f/180f*Math.PI);
|
||||
public static Matrix matProj = new Matrix(
|
||||
new float[][]{
|
||||
{fAspectRatio*fFovRad,0,0,0},
|
||||
{0,fFovRad,0,0},
|
||||
{0,0,fFar/(fFar-fNear),1f},
|
||||
{0,0,(-fFar*fNear)/(fFar-fNear),0f},
|
||||
});
|
||||
|
||||
public void runGameLoop() {
|
||||
rot+=Math.PI/480d;
|
||||
}
|
||||
|
||||
SigRenderer(JFrame f) {
|
||||
|
||||
tri = new Triangle(new Vector3f(-1,-1,0),new Vector3f(0,-1,0),new Vector3f(-1,0,0));
|
||||
tri2 = new Triangle(new Vector3f(-1,0,0),new Vector3f(0,-1,0),new Vector3f(0,0,0));
|
||||
tri3 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,0),new Vector3f(0,-1,-1));
|
||||
tri4 = new Triangle(new Vector3f(0,-1,-1),new Vector3f(0,0,-1),new Vector3f(0,-1,0));
|
||||
/*tri5 = new Triangle(new Vector3f(0,-1,0),new Vector3f(0,-1,-1),new Vector3f(0,0,0));
|
||||
tri6 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,-1),new Vector3f(0,0,-1));*/
|
||||
cube = new Mesh(Arrays.asList(
|
||||
new Triangle[]{
|
||||
new Triangle(new Vector3f(),new Vector3f(0,1,0),new Vector3f(1,1,0)),
|
||||
new Triangle(new Vector3f(),new Vector3f(1,1,0),new Vector3f(1,0,0)),
|
||||
new Triangle(new Vector3f(1,0,0),new Vector3f(1,1,0),new Vector3f(1,1,1)),
|
||||
new Triangle(new Vector3f(1,0,0),new Vector3f(1,1,1),new Vector3f(1,0,1)),
|
||||
new Triangle(new Vector3f(0,1,0),new Vector3f(0,1,1),new Vector3f(1,1,0)),
|
||||
new Triangle(new Vector3f(0,1,1),new Vector3f(1,1,1),new Vector3f(1,1,0)),
|
||||
new Triangle(new Vector3f(),new Vector3f(0,0,1),new Vector3f(1,0,0)),
|
||||
new Triangle(new Vector3f(0,0,1),new Vector3f(1,0,1),new Vector3f(1,0,0)),
|
||||
new Triangle(new Vector3f(0,0,1),new Vector3f(0,1,1),new Vector3f(1,0,1)),
|
||||
new Triangle(new Vector3f(0,1,1),new Vector3f(1,1,1),new Vector3f(1,0,1)),
|
||||
new Triangle(new Vector3f(),new Vector3f(0,1,0),new Vector3f(0,0,1)),
|
||||
new Triangle(new Vector3f(0,1,0),new Vector3f(0,1,1),new Vector3f(0,0,1)),
|
||||
}));
|
||||
|
||||
Panel p = new Panel();
|
||||
|
||||
f.getContentPane().addMouseListener(this);
|
||||
f.getContentPane().addMouseMotionListener(this);
|
||||
f.addKeyListener(this);
|
||||
f.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
|
||||
f.add(p,BorderLayout.CENTER);
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setVisible(true);
|
||||
p.init();
|
||||
|
||||
|
||||
new Thread() {
|
||||
public void run(){
|
||||
while (true) {
|
||||
@ -67,15 +102,6 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
f.getContentPane().addMouseListener(this);
|
||||
f.getContentPane().addMouseMotionListener(this);
|
||||
f.addKeyListener(this);
|
||||
f.add(p);
|
||||
f.setSize(SCREEN_WIDTH,SCREEN_HEIGHT);
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setVisible(true);
|
||||
p.init();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
JFrame f = new JFrame("SigRenderer");
|
||||
|
@ -9,6 +9,10 @@ public class Triangle {
|
||||
this.C=C;
|
||||
}
|
||||
@Override
|
||||
protected Object clone(){
|
||||
return new Triangle((Vector3f)this.A.clone(),(Vector3f)this.B.clone(),(Vector3f)this.C.clone());
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Triangle [A=" + A + ", B=" + B + ", C=" + C + "]";
|
||||
}
|
||||
|
68
src/sig/utils/DrawUtils.java
Normal file
68
src/sig/utils/DrawUtils.java
Normal file
@ -0,0 +1,68 @@
|
||||
package sig.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import sig.SigRenderer;
|
||||
|
||||
public class DrawUtils {
|
||||
public static void DrawTriangle(int[]canvas,int x1,int y1,int x2,int y2,int x3,int y3,Color col) {
|
||||
DrawLine(canvas,x1,y1,x2,y2,col);
|
||||
DrawLine(canvas,x2,y2,x3,y3,col);
|
||||
DrawLine(canvas,x3,y3,x1,y1,col);
|
||||
}
|
||||
public static void DrawLine(int[] canvas,int x1,int y1,int x2,int y2,Color col) {
|
||||
int x,y,dx,dy,dx1,dy1,px,py,xe,ye,i;
|
||||
dx=x2-x1;dy=y2-y1;
|
||||
dx1=Math.abs(dx);dy1=Math.abs(dy);
|
||||
px=2*dy1-dx1;py=2*dx1-dy1;
|
||||
if (dy1<=dx1) {
|
||||
if (dx>=0) {
|
||||
x=x1;y=y1;xe=x2;
|
||||
} else {
|
||||
x=x2;y=y2;xe=x1;
|
||||
}
|
||||
Draw(canvas,x,y,col);
|
||||
for (i=0;x<xe;i++) {
|
||||
x=x+1;
|
||||
if (px<0) {
|
||||
px=px+2*dy1;
|
||||
} else {
|
||||
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
|
||||
y=y+1;
|
||||
} else {
|
||||
y=y-1;
|
||||
}
|
||||
px=px+2*(dy1-dx1);
|
||||
}
|
||||
Draw(canvas,x,y,col);
|
||||
}
|
||||
} else {
|
||||
if (dy>=0) {
|
||||
x=x1;y=y1;ye=y2;
|
||||
} else {
|
||||
x=x2;y=y2;ye=y1;
|
||||
}
|
||||
Draw(canvas,x,y,col);
|
||||
for (i=0;y<ye;i++) {
|
||||
y=y+1;
|
||||
if (py<=0) {
|
||||
py=py+2*dx1;
|
||||
} else {
|
||||
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
|
||||
x=x+1;
|
||||
} else {
|
||||
x=x-1;
|
||||
}
|
||||
py=py+2*(dx1-dy1);
|
||||
}
|
||||
Draw(canvas,x,y,col);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void Draw(int[] canvas,int x,int y,Color col) {
|
||||
if (x>=0&&y>=0&&x<SigRenderer.SCREEN_WIDTH&&y<SigRenderer.SCREEN_HEIGHT) {
|
||||
//System.out.println(x+","+y);
|
||||
canvas[x+y*SigRenderer.SCREEN_WIDTH]=col.getRGB();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user