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.swing.JPanel;
|
||||||
import javax.vecmath.Vector3f;
|
import javax.vecmath.Vector3f;
|
||||||
|
|
||||||
|
import sig.utils.DrawUtils;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
private MemoryImageSource mImageProducer;
|
private MemoryImageSource mImageProducer;
|
||||||
private ColorModel cm;
|
private ColorModel cm;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
float fTheta=0f;
|
||||||
|
|
||||||
public Panel() {
|
public Panel() {
|
||||||
super(true);
|
super(true);
|
||||||
@ -46,6 +49,8 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
cm = getCompatibleColorModel();
|
cm = getCompatibleColorModel();
|
||||||
width = getWidth();
|
width = getWidth();
|
||||||
height = getHeight();
|
height = getHeight();
|
||||||
|
SigRenderer.SCREEN_WIDTH=getWidth();
|
||||||
|
SigRenderer.SCREEN_HEIGHT=getHeight();
|
||||||
int screenSize = width * height;
|
int screenSize = width * height;
|
||||||
if(pixel == null || pixel.length < screenSize){
|
if(pixel == null || pixel.length < screenSize){
|
||||||
pixel = new int[screenSize];
|
pixel = new int[screenSize];
|
||||||
@ -64,6 +69,7 @@ public class Panel extends JPanel implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public /* abstract */ void render(){
|
public /* abstract */ void render(){
|
||||||
int[] p = pixel; // this avoid crash when resizing
|
int[] p = pixel; // this avoid crash when resizing
|
||||||
|
//a=h/w
|
||||||
|
|
||||||
final int h=SigRenderer.SCREEN_HEIGHT;
|
final int h=SigRenderer.SCREEN_HEIGHT;
|
||||||
if(p.length != width * height) return;
|
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;
|
i += 1;
|
||||||
j += 1;
|
j += 1;
|
||||||
endTime=System.nanoTime();
|
endTime=System.nanoTime();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package sig;
|
package sig;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.vecmath.Matrix4f;
|
||||||
import javax.vecmath.Point2d;
|
import javax.vecmath.Point2d;
|
||||||
import javax.vecmath.Tuple3d;
|
import javax.vecmath.Tuple3d;
|
||||||
import javax.vecmath.Vector3f;
|
import javax.vecmath.Vector3f;
|
||||||
@ -9,14 +10,17 @@ import java.awt.event.MouseMotionListener;
|
|||||||
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.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
|
||||||
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
public class SigRenderer implements KeyListener,MouseListener,MouseMotionListener{
|
||||||
public static Triangle tri,tri2,tri3,tri4,tri5,tri6;
|
public static Mesh cube;
|
||||||
public final static int SCREEN_WIDTH=1280;
|
public static int SCREEN_WIDTH=1280;
|
||||||
public final static int SCREEN_HEIGHT=720;
|
public static int SCREEN_HEIGHT=720;
|
||||||
public final static long TIMEPERTICK = 16666667l;
|
public final static long TIMEPERTICK = 16666667l;
|
||||||
public static float DRAWTIME=0;
|
public static float DRAWTIME=0;
|
||||||
public static float DRAWLOOPTIME=0;
|
public static float DRAWLOOPTIME=0;
|
||||||
@ -27,21 +31,52 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
|||||||
|
|
||||||
public static List<Pixel> pixels;
|
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() {
|
public void runGameLoop() {
|
||||||
rot+=Math.PI/480d;
|
rot+=Math.PI/480d;
|
||||||
}
|
}
|
||||||
|
|
||||||
SigRenderer(JFrame f) {
|
SigRenderer(JFrame f) {
|
||||||
|
cube = new Mesh(Arrays.asList(
|
||||||
tri = new Triangle(new Vector3f(-1,-1,0),new Vector3f(0,-1,0),new Vector3f(-1,0,0));
|
new Triangle[]{
|
||||||
tri2 = new Triangle(new Vector3f(-1,0,0),new Vector3f(0,-1,0),new Vector3f(0,0,0));
|
new Triangle(new Vector3f(),new Vector3f(0,1,0),new Vector3f(1,1,0)),
|
||||||
tri3 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,0),new Vector3f(0,-1,-1));
|
new Triangle(new Vector3f(),new Vector3f(1,1,0),new Vector3f(1,0,0)),
|
||||||
tri4 = new Triangle(new Vector3f(0,-1,-1),new Vector3f(0,0,-1),new Vector3f(0,-1,0));
|
new Triangle(new Vector3f(1,0,0),new Vector3f(1,1,0),new Vector3f(1,1,1)),
|
||||||
/*tri5 = new Triangle(new Vector3f(0,-1,0),new Vector3f(0,-1,-1),new Vector3f(0,0,0));
|
new Triangle(new Vector3f(1,0,0),new Vector3f(1,1,1),new Vector3f(1,0,1)),
|
||||||
tri6 = new Triangle(new Vector3f(0,0,0),new Vector3f(0,-1,-1),new Vector3f(0,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();
|
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() {
|
new Thread() {
|
||||||
public void run(){
|
public void run(){
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -67,15 +102,6 @@ public class SigRenderer implements KeyListener,MouseListener,MouseMotionListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.start();
|
}.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) {
|
public static void main(String[] args) {
|
||||||
JFrame f = new JFrame("SigRenderer");
|
JFrame f = new JFrame("SigRenderer");
|
||||||
|
@ -9,6 +9,10 @@ public class Triangle {
|
|||||||
this.C=C;
|
this.C=C;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
protected Object clone(){
|
||||||
|
return new Triangle((Vector3f)this.A.clone(),(Vector3f)this.B.clone(),(Vector3f)this.C.clone());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Triangle [A=" + A + ", B=" + B + ", C=" + C + "]";
|
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