Advertisement
Guest User

Untitled

a guest
Jun 19th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 24.27 KB | None | 0 0
  1. import java.awt.Frame;
  2. import java.awt.event.KeyAdapter;
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.MouseAdapter;
  5. import java.awt.event.MouseEvent;
  6. import java.awt.event.WindowAdapter;
  7. import java.awt.event.WindowEvent;
  8.  
  9.  
  10. public class Game extends Frame {
  11.     static final int up = 1 << 0, down = 1 << 1, left = 1 << 2, right = 1 << 3;
  12.     static final int width = 512, height = 384;
  13.    
  14.     private Object3d[] objects = new Object3d[1];
  15.     private Renderer renderer = new Renderer();
  16.     private RenderSurface surface = new RenderSurface();
  17.     private boolean[] keys = new boolean[256];
  18.    
  19.     public Game() {
  20.         super("helloWorld");
  21.         objects[0] = new Object3d(0, 0, 0, 3);
  22.         surface.setSize(width, height);
  23.         surface.addKeyListener(new KeyHandler());
  24.         surface.addMouseMotionListener(new MouseHandler());
  25.         setResizable(false);
  26.         addWindowListener(new WindowAdapter() {
  27.             public void windowClosing(WindowEvent e) { System.exit(0); }
  28.         });
  29.         add(surface);
  30.         pack();
  31.         setLocationRelativeTo(null);
  32.         setVisible(true);
  33.        
  34.         surface.setup(width, height);
  35.         surface.requestFocus();
  36.     }
  37.    
  38.     private int lastX, lastY;
  39.     private void processMouse(MouseEvent e) {
  40.         int x = e.getX(), y = e.getY();
  41.         int dx = x - lastX, dy = y - lastY;
  42.         if(dx > 0)
  43.             renderer.yaw++;
  44.         else if(dx < 0)
  45.             renderer.yaw--;
  46.         if(dy > 0)
  47.             renderer.pitch--;
  48.         else if(dy < 0)
  49.             renderer.pitch++;
  50.        
  51.         renderer.pitch &= 0xff;
  52.         renderer.yaw &= 0xff;
  53.         lastX = x;
  54.         lastY = y;
  55.     }
  56.    
  57.     private void checkKeys() {
  58.         if(keys[KeyEvent.VK_T]) {
  59.             renderer.texture = (renderer.texture + 1) & 3;
  60.             keys[KeyEvent.VK_T] = false;
  61.         }
  62.     }
  63.    
  64.     public void run() throws Exception {
  65.         while(true) {
  66.             long start = System.currentTimeMillis();
  67.             checkKeys();
  68.             renderer.render(objects, surface);
  69.             int tm = renderer.texture;
  70.             String mode = tm == 0 ? "no" : tm == 1 ? "linear" : tm == 2 ? "perspective" : "off";
  71.             surface.drawString("t to toggle texture mode", 0, 0);
  72.             surface.drawString("mouse to move cube", 0, 13);
  73.             surface.drawString(mode, 0, 371);
  74.             surface.blit();
  75.             long end = System.currentTimeMillis();
  76.             long duration = end - start;
  77.             if(duration > 15) {
  78.                 System.out.println(duration + " > 15");
  79.                 duration = 14;
  80.             }
  81.             Thread.sleep(15 - duration);
  82.         }
  83.     }
  84.    
  85.     public static void main(String[] args) {
  86.         try {
  87.             new Game().run();
  88.         } catch (Exception e) {
  89.             e.printStackTrace();
  90.         }
  91.     }
  92.    
  93.     class KeyHandler extends KeyAdapter {
  94.         public void keyPressed(KeyEvent e) {
  95.             keys[e.getKeyCode()] = true;
  96.         }
  97.        
  98.         public void keyReleased(KeyEvent e) {
  99.             keys[e.getKeyCode()] = false;
  100.         }
  101.     }
  102.    
  103.     class MouseHandler extends MouseAdapter {
  104.         public void mouseDragged(MouseEvent e) {
  105.             Game.this.processMouse(e);
  106.         }
  107.     }
  108. }
  109.  
  110. import java.awt.image.BufferedImage;
  111.  
  112. import javax.imageio.ImageIO;
  113.  
  114. public class Model {
  115.     public static Model[] models;
  116.     public static int[][] textures;
  117.     public static int[] texavg;
  118.    
  119.     public int[] vertX;
  120.     public int[] vertY;
  121.     public int[] vertZ;
  122.     public int numVert;
  123.    
  124.     public double[] transX;
  125.     public double[] transY;
  126.     public double[] transZ;
  127.    
  128.     public int[] screenX;
  129.     public int[] screenY;
  130.    
  131.     public int[] U;
  132.     public int[] V;
  133.     public int numUV;
  134.    
  135.     public int[] clippedX;
  136.     public int[] clippedY;
  137.     public int[] clippedZ;
  138.     public int numClipped;
  139.    
  140.     public int[][] faceverts;
  141.     public int[][] faceuv;
  142.     public int[] facetextid;
  143.     public int numFace;
  144.    
  145.     public int[][] clippedfaceverts;
  146.     public int[][] clippedfaceuv;
  147.     public int[] clippedfacetextid;
  148.     public int numClippedFace;
  149.    
  150.     public Model() {
  151.         this.vertX = new int[50];
  152.         this.vertY = new int[50];
  153.         this.vertZ = new int[50];
  154.         this.transX = new double[50];
  155.         this.transY = new double[50];
  156.         this.transZ = new double[50];
  157.         this.screenX = new int[50];
  158.         this.screenY = new int[50];
  159.         this.U = new int[50];
  160.         this.V = new int[50];
  161.         this.clippedX = new int[50];
  162.         this.clippedY = new int[50];
  163.         this.clippedZ = new int[50];
  164.         this.faceverts = new int[50][];
  165.         this.faceuv = new int[50][];
  166.         this.facetextid = new int[50];
  167.         this.clippedfaceverts = new int[50][];
  168.         this.clippedfaceuv = new int[50][];
  169.         this.clippedfacetextid = new int[50];
  170.     }
  171.    
  172.     public void putVertex(int x, int y, int z) {
  173.         vertX[numVert] = x;
  174.         vertY[numVert] = y;
  175.         vertZ[numVert++] = z;
  176.     }
  177.    
  178.     public void putUV(int u, int v) {
  179.         U[numUV] = u;
  180.         V[numUV++] = v;
  181.     }
  182.    
  183.     public void putFace(int[] vert, int[] uv, int textid) {
  184.         faceverts[numFace] = vert;
  185.         faceuv[numFace] = uv;
  186.         facetextid[numFace++] = textid;
  187.     }
  188.    
  189.     public static void loadTexture(int index, String filename) {
  190.         try {
  191.             BufferedImage img = ImageIO.read(Model.class.getResource(filename));
  192.             int w = img.getWidth();
  193.             int h = img.getHeight();
  194.             int size = w * h;
  195.             if(size < 16384) size = 16384;
  196.             int[] pix = new int[size];
  197.             img.getRGB(0, 0, w, h, pix, 0, w);
  198.            
  199.             long avgr = 0, avgg = 0, avgb = 0;
  200.             for(int k = 0; k < pix.length; k++) {
  201.                 avgr += (pix[k] >> 16) & 0xff;
  202.                 avgg += (pix[k] >>  8) & 0xff;
  203.                 avgb += (pix[k]      ) & 0xff;
  204.             }
  205.             avgr /= pix.length;
  206.             avgg /= pix.length;
  207.             avgb /= pix.length;
  208.            
  209.             textures[index] = pix;
  210.             texavg[index] = (int) ((avgr << 16) | (avgg << 8) | avgb);
  211.         } catch(Exception e) {
  212.             e.printStackTrace();
  213.         }
  214.     }
  215.    
  216.     static {
  217.         textures = new int[52][];
  218.         texavg = new int[52];
  219.         for(int k = 0; k < textures.length; k++)
  220.             loadTexture(k, "media/" + k + ".png");
  221.        
  222.         models = new Model[2];
  223.         models[0] = new Cube();
  224.         models[1] = new Plane();
  225.     }
  226.    
  227.     static class Cube extends Model {
  228.         public Cube() {
  229.             putVertex(1, -1, -1);
  230.             putVertex(1, -1, 1);
  231.             putVertex(-1, -1, 1);
  232.             putVertex(-1, -1, -1);
  233.             putVertex(1, 1, -1);
  234.             putVertex(1, 1, 1);
  235.             putVertex(-1, 1, 1);
  236.             putVertex(-1, 1, -1);
  237.            
  238.             putUV(0, 127);
  239.             putUV(0, 0);
  240.             putUV(127, 0);
  241.             putUV(127, 127);
  242.            
  243.             int[] uv = { 0, 1, 2, 3 };
  244.             putFace(new int[] { 0, 1, 2, 3 }, uv, 50); // 16 cardboard
  245.             putFace(new int[] { 4, 7, 6, 5 }, uv, 50);
  246.             putFace(new int[] { 0, 4, 5, 1 }, uv, 50);
  247.             putFace(new int[] { 1, 5, 6, 2 }, uv, 50);
  248.             putFace(new int[] { 2, 6, 7, 3 }, uv, 50);
  249.             putFace(new int[] { 4, 0, 3, 7 }, uv, 50);
  250.         }
  251.     }
  252.    
  253.     static class Plane extends Model {
  254.         public Plane() {
  255.             putVertex(-5, 0, 5);
  256.             putVertex(5, 0, 5);
  257.             putVertex(5, 0, -5);
  258.             putVertex(-5, 0, -5);
  259.             putUV(0, 127);
  260.             putUV(0, 0);
  261.             putUV(127, 0);
  262.             putUV(127, 127);
  263.             putFace(new int[] { 0, 1, 2, 3 }, new int[] { 0, 1, 2, 3 }, 16);
  264.         }
  265.     }
  266. }
  267.  
  268. import java.util.Arrays;
  269.  
  270. public class Renderer {
  271.     static final float[] sines = new float[256];
  272.     static final float[] cosines = new float[256];
  273.    
  274.     public int pitch = 230;
  275.     public int yaw;
  276.    
  277.     public int texture = 2;
  278.    
  279.     private Face[] faces = new Face[500];
  280.     private int cameraX = 0;
  281.     private int cameraY = 0;
  282.     private int cameraZ = 0;
  283.    
  284.     public void render(Object3d[] objs, RenderSurface s) {
  285.         s.clear();
  286.         int numFaces = 0;
  287.         for(int i = 0; i < objs.length; i++) {
  288.             Object3d obj = objs[i];
  289.             if(obj == null || obj.model == null)
  290.                 continue;
  291.             if(obj.baseZ < 0)
  292.                 continue;
  293.            
  294.             Model mod = obj.model;
  295.             for(int v = 0; v < mod.numVert; v++)
  296.                 transform(obj, v, mod.vertX[v], mod.vertY[v], mod.vertZ[v]);
  297.             for(int f = 0; f < mod.numFace; f++) {
  298.                 int[] face = mod.faceverts[f];
  299.                 int[] uv = mod.faceuv[f];
  300.                 if(face == null || uv == null) continue;
  301.                 float faceNormalX = 0, faceNormalY = 0, faceNormalZ = 0;
  302.                 Face fc = new Face(face.length);
  303.                 for(int v = 0; v < face.length; v++) {
  304.                     faceNormalX += mod.transX[face[v]];
  305.                     faceNormalY += mod.transY[face[v]];
  306.                     faceNormalZ += mod.transZ[face[v]];
  307.                     fc.x[v] = mod.screenX[face[v]];
  308.                     fc.y[v] = mod.screenY[face[v]];
  309.                     fc.z[v] = (float) mod.transZ[face[v]];
  310.                     fc.u[v] = mod.U[uv[v]];
  311.                     fc.v[v] = mod.V[uv[v]];
  312.                 }
  313.                 fc.texID = mod.facetextid[f];
  314.                 fc.distance = faceNormalX * faceNormalX + faceNormalY
  315.                         * faceNormalY + faceNormalZ * faceNormalZ;
  316.                 faces[numFaces++] = fc;
  317.             }
  318.         }
  319.         Arrays.sort(faces, 0, numFaces);
  320.         for(int k = numFaces - 1; k >= 0; k--) {
  321.             Face f = faces[k];
  322.             f.draw(s, texture);
  323.         }
  324.     }
  325.    
  326.     public void transform(Object3d o, int v, int x, int y, int z) {
  327.         double transX, transY, transZ;
  328.         x -= cameraX;
  329.         y -= cameraY;
  330.         z -= cameraZ;
  331.        
  332.         transX = (x * cosines[yaw] - z * sines[yaw]);
  333.         transZ = (x * sines[yaw] + z * cosines[yaw]);
  334.        
  335.         transY = (y * cosines[pitch] - transZ * sines[pitch]);
  336.         transZ = (y * sines[pitch] + transZ * cosines[pitch]);
  337.        
  338.         // not correct for normal projection
  339.         transX += o.baseX;
  340.         transY += o.baseY;
  341.         transZ += o.baseZ;
  342.        
  343.         o.model.transX[v] = transX;
  344.         o.model.transY[v] = transY;
  345.         o.model.transZ[v] = transZ;
  346.        
  347.         // this stretches stuff horizontally to fit the aspect ratio
  348.         // of the window, change the scales to change the aspect
  349.         o.model.screenX[v] = (int) (256 *  transX / transZ) + 256;
  350.         o.model.screenY[v] = (int) (192 * -transY / transZ) + 192;
  351.     }
  352.  
  353.     static {
  354.         double d = 0.02454369d;
  355.         for(int k = 0; k < 256; k++) {
  356.             sines[k] = (float) Math.sin(k * d);
  357.             cosines[k] = (float) Math.cos(k * d);
  358.         }
  359.     }
  360. }
  361.  
  362. class Face implements Comparable<Face> {
  363.     int[] x, y, u, v;
  364.     float[] z;
  365.     int texID;
  366.     boolean close;
  367.     double distance;
  368.    
  369.     public Face(int verts) {
  370.         x = new int[verts];
  371.         y = new int[verts];
  372.         u = new int[verts];
  373.         v = new int[verts];
  374.         z = new float[verts];
  375.     }
  376.    
  377.     public int compareTo(Face o) {
  378.         return distance < o.distance ? -1 : 1;
  379.     }
  380.    
  381.     public void draw(RenderSurface s, int mode) {
  382.         if(mode == 2)
  383.             s.perspectiveCorrectPolygon(x, y, z, u, v, Model.textures[texID], 128);
  384.         else if(mode == 1)
  385.             s.texturedPolygon(x, y, u, v, Model.textures[texID], 128);
  386.         else if(mode == 0)
  387.             s.fillPolygon(x, y, Model.texavg[texID]);
  388.     }
  389. }
  390.  
  391. public class Object3d {
  392.     public int id;
  393.     public Model model;
  394.     public int baseX;
  395.     public int baseY;
  396.     public int baseZ;
  397.    
  398.     public Object3d(int id) {
  399.         this.id = id;
  400.         this.model = Model.models[id];
  401.         baseX = baseY = baseZ = 0;
  402.     }
  403.    
  404.     public Object3d(int id, int baseX, int baseY, int baseZ) {
  405.         this.id = id;
  406.         this.model = Model.models[id];
  407.         this.baseX = baseX;
  408.         this.baseY = baseY;
  409.         this.baseZ = baseZ;
  410.     }
  411. }
  412.  
  413. import java.awt.Canvas;
  414. import java.awt.Graphics;
  415. import java.awt.Image;
  416. import java.awt.image.BufferedImage;
  417. import java.awt.image.DirectColorModel;
  418. import java.awt.image.MemoryImageSource;
  419.  
  420. import javax.imageio.ImageIO;
  421.  
  422. public class RenderSurface extends Canvas {
  423.     static final int lineskip = 1;
  424.     static final int[] tex = Model.textures[0];
  425.     static int[] font;
  426.     static int fontw;
  427.    
  428.     private int width, height, numPix;
  429.     private int[] pixels;
  430.     private MemoryImageSource memsrc;
  431.     private Image memimg;
  432.    
  433.     public void setup(int w, int h) {
  434.         width = w;
  435.         height = h;
  436.         numPix = w * h;
  437.         pixels = new int[numPix];
  438.         memsrc = new MemoryImageSource(width, height, new DirectColorModel(32,
  439.                 0xff0000, 0xff00, 0xff), pixels, 0, width);
  440.         memsrc.setAnimated(true);
  441.         memimg = createImage(memsrc);
  442.     }
  443.    
  444.    
  445.     public void test() {
  446.         clear();
  447.         fillTriangle(100, 100, 200, 50, 300, 100,  0xff0000);
  448.         fillTriangle(150, 200, 180, 280, 230, 200, 0x00ff00);
  449.         fillTriangle(502, 100, 502, 190, 402, 190, 0x0000ff);
  450.         fillTriangle(385, 50, 365, 120, 420, 100,  0xff00ff);
  451.         fillTriangle(10, 10, 100, 10, 10, 100,     0x00ffff);
  452.         fillTriangle(10, 100, 10, 190, 100, 190,   0xffff00);
  453.         fillTriangle(402, 10, 502, 10, 502, 100,   0xffffff);
  454.        
  455.         texturedTriangle(263,238,251,224,186,229,0,0,127,0,127,127,
  456.                 tex, 128);
  457.     }
  458.    
  459.     public void clear() {
  460.         for(int k = 0; k < numPix; k++)
  461.             pixels[k] = 0;
  462.     }
  463.     public void blit() { memsrc.newPixels(); repaint(); }
  464.    
  465.     public void paint(Graphics g) {
  466.         g.drawImage(memimg, 0, 0, this);
  467.     }
  468.    
  469.     public void update(Graphics g) { paint(g); }
  470.    
  471.     public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color) {
  472.         float startx, endx;
  473.         float slope21, slope31, slope32;
  474.         float slopeleft, sloperight;
  475.         int temp, off, start, end;
  476.        
  477.         if(y2 < y1) {
  478.             temp = y2;
  479.             y2 = y1;
  480.             y1 = temp;
  481.             temp = x2;
  482.             x2 = x1;
  483.             x1 = temp;
  484.         }
  485.         if(y3 < y1) {
  486.             temp = y3;
  487.             y3 = y1;
  488.             y1 = temp;
  489.             temp = x3;
  490.             x3 = x1;
  491.             x1 = temp;
  492.         }
  493.         if(y3 < y2) {
  494.             temp = y3;
  495.             y3 = y2;
  496.             y2 = temp;
  497.             temp = x3;
  498.             x3 = x2;
  499.             x2 = temp;
  500.         }
  501.        
  502.         if(y1 == y3)
  503.             return;
  504.        
  505.         slope21 = (float) (x2 - x1) / (y2 - y1);
  506.         slope31 = (float) (x3 - x1) / (y3 - y1);
  507.         slope32 = (float) (x3 - x2) / (y3 - y2);
  508.        
  509.         startx = endx = x1;
  510.         if(y1 != y2) {
  511.             if(slope21 > slope31) {
  512.                 slopeleft = slope31;
  513.                 sloperight = slope21;
  514.             } else {
  515.                 slopeleft = slope21;
  516.                 sloperight = slope31;
  517.             }
  518.            
  519.             for(int y = y1; y != y2; y++) {
  520.                 if(y > 0 && y < height && y % lineskip == 0) {
  521.                     off = y * width;
  522.                     start = off + (int) startx;
  523.                     end = off + (int) endx;
  524.                     if(start < off)
  525.                         start = off;
  526.                     if(end > off + width - 1)
  527.                         end = off + width - 1;
  528.                
  529.                     while(start <= end)
  530.                         pixels[start++] = color;
  531.                 }
  532.  
  533.                 startx += slopeleft;
  534.                 endx += sloperight;
  535.             }
  536.         } else {
  537.             if (x1 > x2) {
  538.                 startx = x2;
  539.                 endx = x1;
  540.             } else {
  541.                 startx = x1;
  542.                 endx = x2;
  543.             }
  544.         }
  545.        
  546.         if(y2 != y3) {
  547.             if(slope32 > slope31) {
  548.                 slopeleft  = slope32;
  549.                 sloperight = slope31;
  550.             } else {
  551.                 slopeleft  = slope31;
  552.                 sloperight = slope32;
  553.             }
  554.            
  555.             for(int y = y2; y != y3; y++) {
  556.                 if(y > 0 && y < height && y % lineskip == 0) {
  557.                     off = y * width;
  558.                     start = off + (int) startx;
  559.                     end = off + (int) endx;
  560.                     if(start < off)
  561.                         start = off;
  562.                     if(end > off + width - 1)
  563.                         end = off + width - 1;
  564.                    
  565.                     while(start <= end)
  566.                         pixels[start++] = color;
  567.                 }
  568.                 startx += slopeleft;
  569.                 endx += sloperight;
  570.             }
  571.         }
  572.     }
  573.    
  574.     public void texturedTriangle(int x1, int y1, int x2, int y2, int x3, int y3,
  575.             int u1, int v1, int u2, int v2, int u3, int v3, int[] texture, int sidelen) {
  576.         float startx, endx, startu, endu, startv, endv, dy;
  577.         float slope21, slope31, slope32;
  578.         float du21, dv21, du31, dv31, du32, dv32, dx, du, dv, u, v;
  579.         float slopeleft, sloperight, duleft, duright, dvleft, dvright;
  580.         int temp, off, start, end;
  581.        
  582.         if(y2 < y1) {
  583.             temp = x2; x2 = x1; x1 = temp;
  584.             temp = y2; y2 = y1; y1 = temp;
  585.             temp = u2; u2 = u1; u1 = temp;
  586.             temp = v2; v2 = v1; v1 = temp;
  587.         }
  588.         if(y3 < y1) {
  589.             temp = x3; x3 = x1; x1 = temp;
  590.             temp = y3; y3 = y1; y1 = temp;
  591.             temp = u3; u3 = u1; u1 = temp;
  592.             temp = v3; v3 = v1; v1 = temp;
  593.         }
  594.         if(y3 < y2) {
  595.             temp = x3; x3 = x2; x2 = temp;
  596.             temp = y3; y3 = y2; y2 = temp;
  597.             temp = u3; u3 = u2; u2 = temp;
  598.             temp = v3; v3 = v2; v2 = temp;
  599.         }
  600.        
  601.         if(y1 == y3)
  602.             return;
  603.        
  604.         dy      = 1.0f /  (y2 - y1);
  605.         slope21 = (float) (x2 - x1) * dy;
  606.         du21    = (float) (u2 - u1) * dy;
  607.         dv21    = (float) (v2 - v1) * dy;
  608.        
  609.         dy      = 1.0f /  (y3 - y1);
  610.         slope31 = (float) (x3 - x1) * dy;
  611.         du31    = (float) (u3 - u1) * dy;
  612.         dv31    = (float) (v3 - v1) * dy;
  613.        
  614.         dy      = 1.0f /  (y3 - y2);
  615.         slope32 = (float) (x3 - x2) * dy;
  616.         du32    = (float) (u3 - u2) * dy;
  617.         dv32    = (float) (v3 - v2) * dy;
  618.        
  619.         startx = endx = x1;
  620.         startu = endu = u1;
  621.         startv = endv = v1;
  622.        
  623.         if(y1 != y2) {
  624.             if(slope21 > slope31) {
  625.                 slopeleft = slope31;
  626.                 sloperight = slope21;
  627.                
  628.                 duleft = du31;
  629.                 duright = du21;
  630.                
  631.                 dvleft = dv31;
  632.                 dvright = dv21;
  633.             } else {
  634.                 slopeleft = slope21;
  635.                 sloperight = slope31;
  636.                
  637.                 duleft = du21;
  638.                 duright = du31;
  639.                
  640.                 dvleft = dv21;
  641.                 dvright = dv31;
  642.             }
  643.            
  644.             for(int y = y1; y != y2; y++) {
  645.                 if(y > 0 && y < height && y % lineskip == 0) {
  646.                     dx = endx - startx;
  647.                     if(dx != 0) {
  648.                         du = (endu - startu) / dx;
  649.                         dv = (endv - startv) / dx;
  650.                     } else {
  651.                         du = endu - startu;
  652.                         dv = endv - startv;
  653.                     }
  654.                     u = startu;
  655.                     v = startv;
  656.                    
  657.                     off = y * width;
  658.                     start = off + (int) startx;
  659.                     end = off + (int) endx;
  660.                     if(start < off) {
  661.                         dx = -startx;
  662.                         u += dx * du;
  663.                         v += dx * dv;
  664.                         start = off;
  665.                     }
  666.                     if(end > off + width - 1)
  667.                         end = off + width - 1;
  668.                
  669.                     while(start < end) {
  670.                         pixels[start++] = texture[(int) v * sidelen + (int) u];
  671.                         u += du;
  672.                         v += dv;
  673.                     }
  674.                 }
  675.  
  676.                 startx += slopeleft;
  677.                 endx += sloperight;
  678.                
  679.                 startu += duleft;
  680.                 endu += duright;
  681.                
  682.                 startv += dvleft;
  683.                 endv += dvright;
  684.             }
  685.         } else {
  686.             if (x1 > x2) {
  687.                 startx = x2;
  688.                 endx = x1;
  689.                
  690.                 startu = u2;
  691.                 endu = u1;
  692.                
  693.                 startv = v2;
  694.                 endv = v1;
  695.             } else {
  696.                 startx = x1;
  697.                 endx = x2;
  698.                
  699.                 startu = u1;
  700.                 endu = u2;
  701.                
  702.                 startv = v1;
  703.                 endv = v2;
  704.             }
  705.         }
  706.        
  707.         if(y2 != y3) {
  708.             if(slope32 > slope31) {
  709.                 slopeleft  = slope32;
  710.                 sloperight = slope31;
  711.                
  712.                 duleft = du32;
  713.                 duright = du31;
  714.                
  715.                 dvleft = dv32;
  716.                 dvright = dv31;
  717.             } else {
  718.                 slopeleft  = slope31;
  719.                 sloperight = slope32;
  720.                
  721.                 duleft = du31;
  722.                 duright = du32;
  723.                
  724.                 dvleft = dv31;
  725.                 dvright = dv32;
  726.             }
  727.            
  728.             for(int y = y2; y != y3; y++) {
  729.                 if(y > 0 && y < height && y % lineskip == 0) {
  730.                     dx = endx - startx;
  731.                     if(dx != 0) {
  732.                         du = (endu - startu) / dx;
  733.                         dv = (endv - startv) / dx;
  734.                     } else {
  735.                         du = endu - startu;
  736.                         dv = endv - startv;
  737.                     }
  738.                     u = startu;
  739.                     v = startv;
  740.  
  741.                     off = y * width;
  742.                     start = off + (int) startx;
  743.                     end = off + (int) endx;
  744.                     if(start < off) {
  745.                         dx = -startx;
  746.                         u += dx * du;
  747.                         v += dx * dv;
  748.                         start = off;
  749.                     }
  750.                     if(end > off + width - 1)
  751.                         end = off + width - 1;
  752.                
  753.                     while(start < end) {
  754.                         pixels[start++] = texture[(int) v * sidelen + (int) u];
  755.                         u += du;
  756.                         v += dv;
  757.                     }
  758.                 }
  759.                 startx += slopeleft;
  760.                 endx += sloperight;
  761.                
  762.                 startu += duleft;
  763.                 endu += duright;
  764.                
  765.                 startv += dvleft;
  766.                 endv += dvright;
  767.             }
  768.         }
  769.     }
  770.    
  771.     static float dizdx, duizdx, dvizdx, dizdy, duizdy, dvizdy;
  772.     static float xa, xb, iza, uiza, viza;
  773.     static float dxdya, dxdyb, dizdya, duizdya, dvizdya;
  774.  
  775.     public void perspectiveCorrectTriangle(float x1, float y1, float z1,
  776.             float x2, float y2, float z2, float x3, float y3, float z3, int u1,
  777.             int v1, int u2, int v2, int u3, int v3, int[] tex, int sidelen) {
  778.         float iz1, uiz1, viz1, iz2, uiz2, viz2, iz3, uiz3, viz3;
  779.         float dxdy1 = 0, dxdy2 = 0, dxdy3 = 0;
  780.         float tempf;
  781.         float det;
  782.         float dy;
  783.         int y1i, y2i, y3i;
  784.         boolean side;
  785.  
  786.         x1 += 0.5f; y1 += 0.5f;
  787.         x2 += 0.5f; y2 += 0.5f;
  788.         x3 += 0.5f; y3 += 0.5f;
  789.        
  790.         iz1 = 1.0f / z1;
  791.         iz2 = 1.0f / z2;
  792.         iz3 = 1.0f / z3;
  793.         uiz1 = u1 * iz1;
  794.         viz1 = v1 * iz1;
  795.         uiz2 = u2 * iz2;
  796.         viz2 = v2 * iz2;
  797.         uiz3 = u3 * iz3;
  798.         viz3 = v3 * iz3;
  799.  
  800.         if (y1 > y2) {
  801.             tempf = x1; x1 = x2; x2 = tempf;
  802.             tempf = y1; y1 = y2; y2 = tempf;
  803.             tempf = iz1; iz1 = iz2; iz2 = tempf;
  804.             tempf = uiz1; uiz1 = uiz2; uiz2 = tempf;
  805.             tempf = viz1; viz1 = viz2; viz2 = tempf;
  806.  
  807.         }
  808.         if (y1 > y3) {
  809.             tempf = x1; x1 = x3; x3 = tempf;
  810.             tempf = y1; y1 = y3; y3 = tempf;
  811.             tempf = iz1; iz1 = iz3; iz3 = tempf;
  812.             tempf = uiz1; uiz1 = uiz3; uiz3 = tempf;
  813.             tempf = viz1; viz1 = viz3; viz3 = tempf;
  814.         }
  815.         if (y2 > y3) {
  816.             tempf = x2; x2 = x3; x3 = tempf;
  817.             tempf = y2; y2 = y3; y3 = tempf;
  818.             tempf = iz2; iz2 = iz3; iz3 = tempf;
  819.             tempf = uiz2; uiz2 = uiz3; uiz3 = tempf;
  820.             tempf = viz2; viz2 = viz3; viz3 = tempf;
  821.         }
  822.  
  823.         y1i = (int) y1;
  824.         y2i = (int) y2;
  825.         y3i = (int) y3;
  826.  
  827.         if (y1 == y3)
  828.             return;
  829.  
  830.         det = ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1));
  831.  
  832.         if (det == 0)
  833.             return;
  834.  
  835.         det = 1 / det;
  836.         dizdx = ((iz3 - iz1) * (y2 - y1) - (iz2 - iz1) * (y3 - y1)) * det;
  837.         duizdx = ((uiz3 - uiz1) * (y2 - y1) - (uiz2 - uiz1) * (y3 - y1)) * det;
  838.         dvizdx = ((viz3 - viz1) * (y2 - y1) - (viz2 - viz1) * (y3 - y1)) * det;
  839.         dizdy = ((iz2 - iz1) * (x3 - x1) - (iz3 - iz1) * (x2 - x1)) * det;
  840.         duizdy = ((uiz2 - uiz1) * (x3 - x1) - (uiz3 - uiz1) * (x2 - x1)) * det;
  841.         dvizdy = ((viz2 - viz1) * (x3 - x1) - (viz3 - viz1) * (x2 - x1)) * det;
  842.  
  843.         if (y2 > y1)
  844.             dxdy1 = (x2 - x1) / (y2 - y1);
  845.         if (y3 > y1)
  846.             dxdy2 = (x3 - x1) / (y3 - y1);
  847.         if (y3 > y2)
  848.             dxdy3 = (x3 - x2) / (y3 - y2);
  849.  
  850.         side = dxdy2 > dxdy1;
  851.  
  852.         if (y1 == y2)
  853.             side = x1 > x2;
  854.         if (y2 == y3)
  855.             side = x3 > x2;
  856.  
  857.         if (!side) {
  858.             dxdya = dxdy2;
  859.             dizdya = dxdy2 * dizdx + dizdy;
  860.             duizdya = dxdy2 * duizdx + duizdy;
  861.             dvizdya = dxdy2 * dvizdx + dvizdy;
  862.  
  863.             dy = 1 - (y1 - y1i);
  864.             xa = x1 + dy * dxdya;
  865.             iza = iz1 + dy * dizdya;
  866.             uiza = uiz1 + dy * duizdya;
  867.             viza = viz1 + dy * dvizdya;
  868.  
  869.             if (y1i < y2i) {
  870.                 xb = x1 + dy * dxdy1;
  871.                 dxdyb = dxdy1;
  872.  
  873.                 perspectiveCorrectSegment(y1i, y2i, tex, sidelen);
  874.             }
  875.             if (y2i < y3i) {
  876.                 xb = x2 + (1 - (y2 - y2i)) * dxdy3;
  877.                 dxdyb = dxdy3;
  878.  
  879.                 perspectiveCorrectSegment(y2i, y3i, tex, sidelen);
  880.             }
  881.         } else {
  882.             dxdyb = dxdy2;
  883.             dy = 1 - (y1 - y1i);
  884.             xb = x1 + dy * dxdyb;
  885.  
  886.             if (y1i < y2i) {
  887.                 dxdya = dxdy1;
  888.                 dizdya = dxdy1 * dizdx + dizdy;
  889.                 duizdya = dxdy1 * duizdx + duizdy;
  890.                 dvizdya = dxdy1 * dvizdx + dvizdy;
  891.                 xa = x1 + dy * dxdya;
  892.                 iza = iz1 + dy * dizdya;
  893.                 uiza = uiz1 + dy * duizdya;
  894.                 viza = viz1 + dy * dvizdya;
  895.  
  896.                 perspectiveCorrectSegment(y1i, y2i, tex, sidelen);
  897.             }
  898.             if (y2i < y3i) {
  899.                 dxdya = dxdy3;
  900.                 dizdya = dxdy3 * dizdx + dizdy;
  901.                 duizdya = dxdy3 * duizdx + duizdy;
  902.                 dvizdya = dxdy3 * dvizdx + dvizdy;
  903.                 dy = 1 - (y2 - y2i);
  904.                 xa = x2 + dy * dxdya;
  905.                 iza = iz2 + dy * dizdya;
  906.                 uiza = uiz2 + dy * duizdya;
  907.                 viza = viz2 + dy * dvizdya;
  908.  
  909.                 perspectiveCorrectSegment(y2i, y3i, tex, sidelen);
  910.             }
  911.         }
  912.     }
  913.  
  914.     private void perspectiveCorrectSegment(int y1, int y2, int[] tex, int sidelen) {
  915.         int scr, idx;
  916.         int x1, x2;
  917.         float z, u, v, dx;
  918.         float iz, uiz, viz;
  919.  
  920.         while (y1 < y2) {
  921.             if (y1 % lineskip == 0) {
  922.                 x1 = (int) xa;
  923.                 x2 = (int) xb;
  924.                 if(x1 < 0)
  925.                     x1 = 0;
  926.                 if (x2 > width - 1)
  927.                     x2 = width - 1;
  928.                
  929.                 dx = 1 - (xa - x1);
  930.                 iz = iza + dx * dizdx;
  931.                 uiz = uiza + dx * duizdx;
  932.                 viz = viza + dx * dvizdx;
  933.                 scr = y1 * width + x1;
  934.                
  935.                 while (x1++ < x2) {
  936.                     if(scr < 0 || scr > pixels.length - 1)
  937.                         continue;
  938.                     z = 1 / iz;
  939.                     u = uiz * z;
  940.                     v = viz * z;
  941.                    
  942.                     idx = ((int) v & (sidelen - 1)) * sidelen + ((int) u & (sidelen - 1));
  943.                     pixels[scr++] = tex[idx];
  944.                     iz += dizdx;
  945.                     uiz += duizdx;
  946.                     viz += dvizdx;
  947.                 }
  948.  
  949.             }
  950.             xa += dxdya;
  951.             xb += dxdyb;
  952.             iza += dizdya;
  953.             uiza += duizdya;
  954.             viza += dvizdya;
  955.            
  956.             y1++;
  957.         }
  958.     }
  959.    
  960.     public void drawString(String s, int x, int y) {
  961.         char[] ch = s.toCharArray();
  962.         for(int k = 0; k < ch.length; k++) {
  963.             drawChar(ch[k], x, y);
  964.             x += 7;
  965.         }
  966.     }
  967.    
  968.     public void drawChar(char c, int x, int y) {
  969.         int off = y * width + x;
  970.         int srcoff = 0;
  971.         if(c >= '0' && c <= '9')
  972.             srcoff = c - '0' + 1;
  973.         else if(c >= 'A' && c <= 'Z')
  974.             srcoff = c - 'A' + 11;
  975.         else if(c >= 'a' && c <= 'z')
  976.             srcoff = c - 'a' + 37;
  977.         srcoff *= 7;
  978.         for(int k = 0; k < 13; k++) {
  979.             for (int p = 0; p < 7; p++, off++, srcoff++) {
  980.                 if (font[srcoff] != 0)
  981.                     pixels[off] = font[srcoff];
  982.             }
  983.  
  984.             srcoff += fontw - 7;
  985.             off += width - 7;
  986.         }
  987.     }
  988.    
  989.     public void fillPolygon(int[] x, int[] y, int color) {
  990.         for (int k = 2; k < x.length; k++) {
  991.             fillTriangle(x[0], y[0], x[k - 1], y[k - 1], x[k], y[k], color);
  992.         }
  993.     }
  994.    
  995.     public void texturedPolygon(int[] x, int[] y, int[] u, int[] v, int[] texture, int sidelen) {
  996.         for (int k = 2; k < x.length; k++) {
  997.             texturedTriangle(x[0], y[0], x[k - 1], y[k - 1], x[k], y[k], u[0],
  998.                     v[0], u[k - 1], v[k - 1], u[k], v[k], texture, sidelen);
  999.         }
  1000.     }
  1001.    
  1002.     public void perspectiveCorrectPolygon(int[] x, int[] y, float[] z, int[] u, int[] v,
  1003.             int[] texture, int sidelen) {
  1004.         for (int k = 2; k < x.length; k++) {
  1005.             perspectiveCorrectTriangle(x[0], y[0], z[0], x[k - 1], y[k - 1],
  1006.                     z[k - 1], x[k], y[k], z[k], u[0], v[0], u[k - 1], v[k - 1],
  1007.                     u[k], v[k], texture, sidelen);
  1008.         }
  1009.     }
  1010.    
  1011.     static {
  1012.         try {
  1013.             BufferedImage fimg = ImageIO.read(RenderSurface.class.getResource("media/font.png"));
  1014.             int w = fimg.getWidth();
  1015.             int h = fimg.getHeight();
  1016.             fontw = w;
  1017.             font = new int[w * h];
  1018.             fimg.getRGB(0, 0, w, h, font, 0, w);
  1019.         } catch(Exception e) {
  1020.             e.printStackTrace();
  1021.         }
  1022.     }
  1023. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement