Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Frame;
- import java.awt.event.KeyAdapter;
- import java.awt.event.KeyEvent;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- public class Game extends Frame {
- static final int up = 1 << 0, down = 1 << 1, left = 1 << 2, right = 1 << 3;
- static final int width = 512, height = 384;
- private Object3d[] objects = new Object3d[1];
- private Renderer renderer = new Renderer();
- private RenderSurface surface = new RenderSurface();
- private boolean[] keys = new boolean[256];
- public Game() {
- super("helloWorld");
- objects[0] = new Object3d(0, 0, 0, 3);
- surface.setSize(width, height);
- surface.addKeyListener(new KeyHandler());
- surface.addMouseMotionListener(new MouseHandler());
- setResizable(false);
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) { System.exit(0); }
- });
- add(surface);
- pack();
- setLocationRelativeTo(null);
- setVisible(true);
- surface.setup(width, height);
- surface.requestFocus();
- }
- private int lastX, lastY;
- private void processMouse(MouseEvent e) {
- int x = e.getX(), y = e.getY();
- int dx = x - lastX, dy = y - lastY;
- if(dx > 0)
- renderer.yaw++;
- else if(dx < 0)
- renderer.yaw--;
- if(dy > 0)
- renderer.pitch--;
- else if(dy < 0)
- renderer.pitch++;
- renderer.pitch &= 0xff;
- renderer.yaw &= 0xff;
- lastX = x;
- lastY = y;
- }
- private void checkKeys() {
- if(keys[KeyEvent.VK_T]) {
- renderer.texture = (renderer.texture + 1) & 3;
- keys[KeyEvent.VK_T] = false;
- }
- }
- public void run() throws Exception {
- while(true) {
- long start = System.currentTimeMillis();
- checkKeys();
- renderer.render(objects, surface);
- int tm = renderer.texture;
- String mode = tm == 0 ? "no" : tm == 1 ? "linear" : tm == 2 ? "perspective" : "off";
- surface.drawString("t to toggle texture mode", 0, 0);
- surface.drawString("mouse to move cube", 0, 13);
- surface.drawString(mode, 0, 371);
- surface.blit();
- long end = System.currentTimeMillis();
- long duration = end - start;
- if(duration > 15) {
- System.out.println(duration + " > 15");
- duration = 14;
- }
- Thread.sleep(15 - duration);
- }
- }
- public static void main(String[] args) {
- try {
- new Game().run();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- class KeyHandler extends KeyAdapter {
- public void keyPressed(KeyEvent e) {
- keys[e.getKeyCode()] = true;
- }
- public void keyReleased(KeyEvent e) {
- keys[e.getKeyCode()] = false;
- }
- }
- class MouseHandler extends MouseAdapter {
- public void mouseDragged(MouseEvent e) {
- Game.this.processMouse(e);
- }
- }
- }
- import java.awt.image.BufferedImage;
- import javax.imageio.ImageIO;
- public class Model {
- public static Model[] models;
- public static int[][] textures;
- public static int[] texavg;
- public int[] vertX;
- public int[] vertY;
- public int[] vertZ;
- public int numVert;
- public double[] transX;
- public double[] transY;
- public double[] transZ;
- public int[] screenX;
- public int[] screenY;
- public int[] U;
- public int[] V;
- public int numUV;
- public int[] clippedX;
- public int[] clippedY;
- public int[] clippedZ;
- public int numClipped;
- public int[][] faceverts;
- public int[][] faceuv;
- public int[] facetextid;
- public int numFace;
- public int[][] clippedfaceverts;
- public int[][] clippedfaceuv;
- public int[] clippedfacetextid;
- public int numClippedFace;
- public Model() {
- this.vertX = new int[50];
- this.vertY = new int[50];
- this.vertZ = new int[50];
- this.transX = new double[50];
- this.transY = new double[50];
- this.transZ = new double[50];
- this.screenX = new int[50];
- this.screenY = new int[50];
- this.U = new int[50];
- this.V = new int[50];
- this.clippedX = new int[50];
- this.clippedY = new int[50];
- this.clippedZ = new int[50];
- this.faceverts = new int[50][];
- this.faceuv = new int[50][];
- this.facetextid = new int[50];
- this.clippedfaceverts = new int[50][];
- this.clippedfaceuv = new int[50][];
- this.clippedfacetextid = new int[50];
- }
- public void putVertex(int x, int y, int z) {
- vertX[numVert] = x;
- vertY[numVert] = y;
- vertZ[numVert++] = z;
- }
- public void putUV(int u, int v) {
- U[numUV] = u;
- V[numUV++] = v;
- }
- public void putFace(int[] vert, int[] uv, int textid) {
- faceverts[numFace] = vert;
- faceuv[numFace] = uv;
- facetextid[numFace++] = textid;
- }
- public static void loadTexture(int index, String filename) {
- try {
- BufferedImage img = ImageIO.read(Model.class.getResource(filename));
- int w = img.getWidth();
- int h = img.getHeight();
- int size = w * h;
- if(size < 16384) size = 16384;
- int[] pix = new int[size];
- img.getRGB(0, 0, w, h, pix, 0, w);
- long avgr = 0, avgg = 0, avgb = 0;
- for(int k = 0; k < pix.length; k++) {
- avgr += (pix[k] >> 16) & 0xff;
- avgg += (pix[k] >> 8) & 0xff;
- avgb += (pix[k] ) & 0xff;
- }
- avgr /= pix.length;
- avgg /= pix.length;
- avgb /= pix.length;
- textures[index] = pix;
- texavg[index] = (int) ((avgr << 16) | (avgg << 8) | avgb);
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- static {
- textures = new int[52][];
- texavg = new int[52];
- for(int k = 0; k < textures.length; k++)
- loadTexture(k, "media/" + k + ".png");
- models = new Model[2];
- models[0] = new Cube();
- models[1] = new Plane();
- }
- static class Cube extends Model {
- public Cube() {
- putVertex(1, -1, -1);
- putVertex(1, -1, 1);
- putVertex(-1, -1, 1);
- putVertex(-1, -1, -1);
- putVertex(1, 1, -1);
- putVertex(1, 1, 1);
- putVertex(-1, 1, 1);
- putVertex(-1, 1, -1);
- putUV(0, 127);
- putUV(0, 0);
- putUV(127, 0);
- putUV(127, 127);
- int[] uv = { 0, 1, 2, 3 };
- putFace(new int[] { 0, 1, 2, 3 }, uv, 50); // 16 cardboard
- putFace(new int[] { 4, 7, 6, 5 }, uv, 50);
- putFace(new int[] { 0, 4, 5, 1 }, uv, 50);
- putFace(new int[] { 1, 5, 6, 2 }, uv, 50);
- putFace(new int[] { 2, 6, 7, 3 }, uv, 50);
- putFace(new int[] { 4, 0, 3, 7 }, uv, 50);
- }
- }
- static class Plane extends Model {
- public Plane() {
- putVertex(-5, 0, 5);
- putVertex(5, 0, 5);
- putVertex(5, 0, -5);
- putVertex(-5, 0, -5);
- putUV(0, 127);
- putUV(0, 0);
- putUV(127, 0);
- putUV(127, 127);
- putFace(new int[] { 0, 1, 2, 3 }, new int[] { 0, 1, 2, 3 }, 16);
- }
- }
- }
- import java.util.Arrays;
- public class Renderer {
- static final float[] sines = new float[256];
- static final float[] cosines = new float[256];
- public int pitch = 230;
- public int yaw;
- public int texture = 2;
- private Face[] faces = new Face[500];
- private int cameraX = 0;
- private int cameraY = 0;
- private int cameraZ = 0;
- public void render(Object3d[] objs, RenderSurface s) {
- s.clear();
- int numFaces = 0;
- for(int i = 0; i < objs.length; i++) {
- Object3d obj = objs[i];
- if(obj == null || obj.model == null)
- continue;
- if(obj.baseZ < 0)
- continue;
- Model mod = obj.model;
- for(int v = 0; v < mod.numVert; v++)
- transform(obj, v, mod.vertX[v], mod.vertY[v], mod.vertZ[v]);
- for(int f = 0; f < mod.numFace; f++) {
- int[] face = mod.faceverts[f];
- int[] uv = mod.faceuv[f];
- if(face == null || uv == null) continue;
- float faceNormalX = 0, faceNormalY = 0, faceNormalZ = 0;
- Face fc = new Face(face.length);
- for(int v = 0; v < face.length; v++) {
- faceNormalX += mod.transX[face[v]];
- faceNormalY += mod.transY[face[v]];
- faceNormalZ += mod.transZ[face[v]];
- fc.x[v] = mod.screenX[face[v]];
- fc.y[v] = mod.screenY[face[v]];
- fc.z[v] = (float) mod.transZ[face[v]];
- fc.u[v] = mod.U[uv[v]];
- fc.v[v] = mod.V[uv[v]];
- }
- fc.texID = mod.facetextid[f];
- fc.distance = faceNormalX * faceNormalX + faceNormalY
- * faceNormalY + faceNormalZ * faceNormalZ;
- faces[numFaces++] = fc;
- }
- }
- Arrays.sort(faces, 0, numFaces);
- for(int k = numFaces - 1; k >= 0; k--) {
- Face f = faces[k];
- f.draw(s, texture);
- }
- }
- public void transform(Object3d o, int v, int x, int y, int z) {
- double transX, transY, transZ;
- x -= cameraX;
- y -= cameraY;
- z -= cameraZ;
- transX = (x * cosines[yaw] - z * sines[yaw]);
- transZ = (x * sines[yaw] + z * cosines[yaw]);
- transY = (y * cosines[pitch] - transZ * sines[pitch]);
- transZ = (y * sines[pitch] + transZ * cosines[pitch]);
- // not correct for normal projection
- transX += o.baseX;
- transY += o.baseY;
- transZ += o.baseZ;
- o.model.transX[v] = transX;
- o.model.transY[v] = transY;
- o.model.transZ[v] = transZ;
- // this stretches stuff horizontally to fit the aspect ratio
- // of the window, change the scales to change the aspect
- o.model.screenX[v] = (int) (256 * transX / transZ) + 256;
- o.model.screenY[v] = (int) (192 * -transY / transZ) + 192;
- }
- static {
- double d = 0.02454369d;
- for(int k = 0; k < 256; k++) {
- sines[k] = (float) Math.sin(k * d);
- cosines[k] = (float) Math.cos(k * d);
- }
- }
- }
- class Face implements Comparable<Face> {
- int[] x, y, u, v;
- float[] z;
- int texID;
- boolean close;
- double distance;
- public Face(int verts) {
- x = new int[verts];
- y = new int[verts];
- u = new int[verts];
- v = new int[verts];
- z = new float[verts];
- }
- public int compareTo(Face o) {
- return distance < o.distance ? -1 : 1;
- }
- public void draw(RenderSurface s, int mode) {
- if(mode == 2)
- s.perspectiveCorrectPolygon(x, y, z, u, v, Model.textures[texID], 128);
- else if(mode == 1)
- s.texturedPolygon(x, y, u, v, Model.textures[texID], 128);
- else if(mode == 0)
- s.fillPolygon(x, y, Model.texavg[texID]);
- }
- }
- public class Object3d {
- public int id;
- public Model model;
- public int baseX;
- public int baseY;
- public int baseZ;
- public Object3d(int id) {
- this.id = id;
- this.model = Model.models[id];
- baseX = baseY = baseZ = 0;
- }
- public Object3d(int id, int baseX, int baseY, int baseZ) {
- this.id = id;
- this.model = Model.models[id];
- this.baseX = baseX;
- this.baseY = baseY;
- this.baseZ = baseZ;
- }
- }
- import java.awt.Canvas;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.image.BufferedImage;
- import java.awt.image.DirectColorModel;
- import java.awt.image.MemoryImageSource;
- import javax.imageio.ImageIO;
- public class RenderSurface extends Canvas {
- static final int lineskip = 1;
- static final int[] tex = Model.textures[0];
- static int[] font;
- static int fontw;
- private int width, height, numPix;
- private int[] pixels;
- private MemoryImageSource memsrc;
- private Image memimg;
- public void setup(int w, int h) {
- width = w;
- height = h;
- numPix = w * h;
- pixels = new int[numPix];
- memsrc = new MemoryImageSource(width, height, new DirectColorModel(32,
- 0xff0000, 0xff00, 0xff), pixels, 0, width);
- memsrc.setAnimated(true);
- memimg = createImage(memsrc);
- }
- public void test() {
- clear();
- fillTriangle(100, 100, 200, 50, 300, 100, 0xff0000);
- fillTriangle(150, 200, 180, 280, 230, 200, 0x00ff00);
- fillTriangle(502, 100, 502, 190, 402, 190, 0x0000ff);
- fillTriangle(385, 50, 365, 120, 420, 100, 0xff00ff);
- fillTriangle(10, 10, 100, 10, 10, 100, 0x00ffff);
- fillTriangle(10, 100, 10, 190, 100, 190, 0xffff00);
- fillTriangle(402, 10, 502, 10, 502, 100, 0xffffff);
- texturedTriangle(263,238,251,224,186,229,0,0,127,0,127,127,
- tex, 128);
- }
- public void clear() {
- for(int k = 0; k < numPix; k++)
- pixels[k] = 0;
- }
- public void blit() { memsrc.newPixels(); repaint(); }
- public void paint(Graphics g) {
- g.drawImage(memimg, 0, 0, this);
- }
- public void update(Graphics g) { paint(g); }
- public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color) {
- float startx, endx;
- float slope21, slope31, slope32;
- float slopeleft, sloperight;
- int temp, off, start, end;
- if(y2 < y1) {
- temp = y2;
- y2 = y1;
- y1 = temp;
- temp = x2;
- x2 = x1;
- x1 = temp;
- }
- if(y3 < y1) {
- temp = y3;
- y3 = y1;
- y1 = temp;
- temp = x3;
- x3 = x1;
- x1 = temp;
- }
- if(y3 < y2) {
- temp = y3;
- y3 = y2;
- y2 = temp;
- temp = x3;
- x3 = x2;
- x2 = temp;
- }
- if(y1 == y3)
- return;
- slope21 = (float) (x2 - x1) / (y2 - y1);
- slope31 = (float) (x3 - x1) / (y3 - y1);
- slope32 = (float) (x3 - x2) / (y3 - y2);
- startx = endx = x1;
- if(y1 != y2) {
- if(slope21 > slope31) {
- slopeleft = slope31;
- sloperight = slope21;
- } else {
- slopeleft = slope21;
- sloperight = slope31;
- }
- for(int y = y1; y != y2; y++) {
- if(y > 0 && y < height && y % lineskip == 0) {
- off = y * width;
- start = off + (int) startx;
- end = off + (int) endx;
- if(start < off)
- start = off;
- if(end > off + width - 1)
- end = off + width - 1;
- while(start <= end)
- pixels[start++] = color;
- }
- startx += slopeleft;
- endx += sloperight;
- }
- } else {
- if (x1 > x2) {
- startx = x2;
- endx = x1;
- } else {
- startx = x1;
- endx = x2;
- }
- }
- if(y2 != y3) {
- if(slope32 > slope31) {
- slopeleft = slope32;
- sloperight = slope31;
- } else {
- slopeleft = slope31;
- sloperight = slope32;
- }
- for(int y = y2; y != y3; y++) {
- if(y > 0 && y < height && y % lineskip == 0) {
- off = y * width;
- start = off + (int) startx;
- end = off + (int) endx;
- if(start < off)
- start = off;
- if(end > off + width - 1)
- end = off + width - 1;
- while(start <= end)
- pixels[start++] = color;
- }
- startx += slopeleft;
- endx += sloperight;
- }
- }
- }
- public void texturedTriangle(int x1, int y1, int x2, int y2, int x3, int y3,
- int u1, int v1, int u2, int v2, int u3, int v3, int[] texture, int sidelen) {
- float startx, endx, startu, endu, startv, endv, dy;
- float slope21, slope31, slope32;
- float du21, dv21, du31, dv31, du32, dv32, dx, du, dv, u, v;
- float slopeleft, sloperight, duleft, duright, dvleft, dvright;
- int temp, off, start, end;
- if(y2 < y1) {
- temp = x2; x2 = x1; x1 = temp;
- temp = y2; y2 = y1; y1 = temp;
- temp = u2; u2 = u1; u1 = temp;
- temp = v2; v2 = v1; v1 = temp;
- }
- if(y3 < y1) {
- temp = x3; x3 = x1; x1 = temp;
- temp = y3; y3 = y1; y1 = temp;
- temp = u3; u3 = u1; u1 = temp;
- temp = v3; v3 = v1; v1 = temp;
- }
- if(y3 < y2) {
- temp = x3; x3 = x2; x2 = temp;
- temp = y3; y3 = y2; y2 = temp;
- temp = u3; u3 = u2; u2 = temp;
- temp = v3; v3 = v2; v2 = temp;
- }
- if(y1 == y3)
- return;
- dy = 1.0f / (y2 - y1);
- slope21 = (float) (x2 - x1) * dy;
- du21 = (float) (u2 - u1) * dy;
- dv21 = (float) (v2 - v1) * dy;
- dy = 1.0f / (y3 - y1);
- slope31 = (float) (x3 - x1) * dy;
- du31 = (float) (u3 - u1) * dy;
- dv31 = (float) (v3 - v1) * dy;
- dy = 1.0f / (y3 - y2);
- slope32 = (float) (x3 - x2) * dy;
- du32 = (float) (u3 - u2) * dy;
- dv32 = (float) (v3 - v2) * dy;
- startx = endx = x1;
- startu = endu = u1;
- startv = endv = v1;
- if(y1 != y2) {
- if(slope21 > slope31) {
- slopeleft = slope31;
- sloperight = slope21;
- duleft = du31;
- duright = du21;
- dvleft = dv31;
- dvright = dv21;
- } else {
- slopeleft = slope21;
- sloperight = slope31;
- duleft = du21;
- duright = du31;
- dvleft = dv21;
- dvright = dv31;
- }
- for(int y = y1; y != y2; y++) {
- if(y > 0 && y < height && y % lineskip == 0) {
- dx = endx - startx;
- if(dx != 0) {
- du = (endu - startu) / dx;
- dv = (endv - startv) / dx;
- } else {
- du = endu - startu;
- dv = endv - startv;
- }
- u = startu;
- v = startv;
- off = y * width;
- start = off + (int) startx;
- end = off + (int) endx;
- if(start < off) {
- dx = -startx;
- u += dx * du;
- v += dx * dv;
- start = off;
- }
- if(end > off + width - 1)
- end = off + width - 1;
- while(start < end) {
- pixels[start++] = texture[(int) v * sidelen + (int) u];
- u += du;
- v += dv;
- }
- }
- startx += slopeleft;
- endx += sloperight;
- startu += duleft;
- endu += duright;
- startv += dvleft;
- endv += dvright;
- }
- } else {
- if (x1 > x2) {
- startx = x2;
- endx = x1;
- startu = u2;
- endu = u1;
- startv = v2;
- endv = v1;
- } else {
- startx = x1;
- endx = x2;
- startu = u1;
- endu = u2;
- startv = v1;
- endv = v2;
- }
- }
- if(y2 != y3) {
- if(slope32 > slope31) {
- slopeleft = slope32;
- sloperight = slope31;
- duleft = du32;
- duright = du31;
- dvleft = dv32;
- dvright = dv31;
- } else {
- slopeleft = slope31;
- sloperight = slope32;
- duleft = du31;
- duright = du32;
- dvleft = dv31;
- dvright = dv32;
- }
- for(int y = y2; y != y3; y++) {
- if(y > 0 && y < height && y % lineskip == 0) {
- dx = endx - startx;
- if(dx != 0) {
- du = (endu - startu) / dx;
- dv = (endv - startv) / dx;
- } else {
- du = endu - startu;
- dv = endv - startv;
- }
- u = startu;
- v = startv;
- off = y * width;
- start = off + (int) startx;
- end = off + (int) endx;
- if(start < off) {
- dx = -startx;
- u += dx * du;
- v += dx * dv;
- start = off;
- }
- if(end > off + width - 1)
- end = off + width - 1;
- while(start < end) {
- pixels[start++] = texture[(int) v * sidelen + (int) u];
- u += du;
- v += dv;
- }
- }
- startx += slopeleft;
- endx += sloperight;
- startu += duleft;
- endu += duright;
- startv += dvleft;
- endv += dvright;
- }
- }
- }
- static float dizdx, duizdx, dvizdx, dizdy, duizdy, dvizdy;
- static float xa, xb, iza, uiza, viza;
- static float dxdya, dxdyb, dizdya, duizdya, dvizdya;
- public void perspectiveCorrectTriangle(float x1, float y1, float z1,
- float x2, float y2, float z2, float x3, float y3, float z3, int u1,
- int v1, int u2, int v2, int u3, int v3, int[] tex, int sidelen) {
- float iz1, uiz1, viz1, iz2, uiz2, viz2, iz3, uiz3, viz3;
- float dxdy1 = 0, dxdy2 = 0, dxdy3 = 0;
- float tempf;
- float det;
- float dy;
- int y1i, y2i, y3i;
- boolean side;
- x1 += 0.5f; y1 += 0.5f;
- x2 += 0.5f; y2 += 0.5f;
- x3 += 0.5f; y3 += 0.5f;
- iz1 = 1.0f / z1;
- iz2 = 1.0f / z2;
- iz3 = 1.0f / z3;
- uiz1 = u1 * iz1;
- viz1 = v1 * iz1;
- uiz2 = u2 * iz2;
- viz2 = v2 * iz2;
- uiz3 = u3 * iz3;
- viz3 = v3 * iz3;
- if (y1 > y2) {
- tempf = x1; x1 = x2; x2 = tempf;
- tempf = y1; y1 = y2; y2 = tempf;
- tempf = iz1; iz1 = iz2; iz2 = tempf;
- tempf = uiz1; uiz1 = uiz2; uiz2 = tempf;
- tempf = viz1; viz1 = viz2; viz2 = tempf;
- }
- if (y1 > y3) {
- tempf = x1; x1 = x3; x3 = tempf;
- tempf = y1; y1 = y3; y3 = tempf;
- tempf = iz1; iz1 = iz3; iz3 = tempf;
- tempf = uiz1; uiz1 = uiz3; uiz3 = tempf;
- tempf = viz1; viz1 = viz3; viz3 = tempf;
- }
- if (y2 > y3) {
- tempf = x2; x2 = x3; x3 = tempf;
- tempf = y2; y2 = y3; y3 = tempf;
- tempf = iz2; iz2 = iz3; iz3 = tempf;
- tempf = uiz2; uiz2 = uiz3; uiz3 = tempf;
- tempf = viz2; viz2 = viz3; viz3 = tempf;
- }
- y1i = (int) y1;
- y2i = (int) y2;
- y3i = (int) y3;
- if (y1 == y3)
- return;
- det = ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1));
- if (det == 0)
- return;
- det = 1 / det;
- dizdx = ((iz3 - iz1) * (y2 - y1) - (iz2 - iz1) * (y3 - y1)) * det;
- duizdx = ((uiz3 - uiz1) * (y2 - y1) - (uiz2 - uiz1) * (y3 - y1)) * det;
- dvizdx = ((viz3 - viz1) * (y2 - y1) - (viz2 - viz1) * (y3 - y1)) * det;
- dizdy = ((iz2 - iz1) * (x3 - x1) - (iz3 - iz1) * (x2 - x1)) * det;
- duizdy = ((uiz2 - uiz1) * (x3 - x1) - (uiz3 - uiz1) * (x2 - x1)) * det;
- dvizdy = ((viz2 - viz1) * (x3 - x1) - (viz3 - viz1) * (x2 - x1)) * det;
- if (y2 > y1)
- dxdy1 = (x2 - x1) / (y2 - y1);
- if (y3 > y1)
- dxdy2 = (x3 - x1) / (y3 - y1);
- if (y3 > y2)
- dxdy3 = (x3 - x2) / (y3 - y2);
- side = dxdy2 > dxdy1;
- if (y1 == y2)
- side = x1 > x2;
- if (y2 == y3)
- side = x3 > x2;
- if (!side) {
- dxdya = dxdy2;
- dizdya = dxdy2 * dizdx + dizdy;
- duizdya = dxdy2 * duizdx + duizdy;
- dvizdya = dxdy2 * dvizdx + dvizdy;
- dy = 1 - (y1 - y1i);
- xa = x1 + dy * dxdya;
- iza = iz1 + dy * dizdya;
- uiza = uiz1 + dy * duizdya;
- viza = viz1 + dy * dvizdya;
- if (y1i < y2i) {
- xb = x1 + dy * dxdy1;
- dxdyb = dxdy1;
- perspectiveCorrectSegment(y1i, y2i, tex, sidelen);
- }
- if (y2i < y3i) {
- xb = x2 + (1 - (y2 - y2i)) * dxdy3;
- dxdyb = dxdy3;
- perspectiveCorrectSegment(y2i, y3i, tex, sidelen);
- }
- } else {
- dxdyb = dxdy2;
- dy = 1 - (y1 - y1i);
- xb = x1 + dy * dxdyb;
- if (y1i < y2i) {
- dxdya = dxdy1;
- dizdya = dxdy1 * dizdx + dizdy;
- duizdya = dxdy1 * duizdx + duizdy;
- dvizdya = dxdy1 * dvizdx + dvizdy;
- xa = x1 + dy * dxdya;
- iza = iz1 + dy * dizdya;
- uiza = uiz1 + dy * duizdya;
- viza = viz1 + dy * dvizdya;
- perspectiveCorrectSegment(y1i, y2i, tex, sidelen);
- }
- if (y2i < y3i) {
- dxdya = dxdy3;
- dizdya = dxdy3 * dizdx + dizdy;
- duizdya = dxdy3 * duizdx + duizdy;
- dvizdya = dxdy3 * dvizdx + dvizdy;
- dy = 1 - (y2 - y2i);
- xa = x2 + dy * dxdya;
- iza = iz2 + dy * dizdya;
- uiza = uiz2 + dy * duizdya;
- viza = viz2 + dy * dvizdya;
- perspectiveCorrectSegment(y2i, y3i, tex, sidelen);
- }
- }
- }
- private void perspectiveCorrectSegment(int y1, int y2, int[] tex, int sidelen) {
- int scr, idx;
- int x1, x2;
- float z, u, v, dx;
- float iz, uiz, viz;
- while (y1 < y2) {
- if (y1 % lineskip == 0) {
- x1 = (int) xa;
- x2 = (int) xb;
- if(x1 < 0)
- x1 = 0;
- if (x2 > width - 1)
- x2 = width - 1;
- dx = 1 - (xa - x1);
- iz = iza + dx * dizdx;
- uiz = uiza + dx * duizdx;
- viz = viza + dx * dvizdx;
- scr = y1 * width + x1;
- while (x1++ < x2) {
- if(scr < 0 || scr > pixels.length - 1)
- continue;
- z = 1 / iz;
- u = uiz * z;
- v = viz * z;
- idx = ((int) v & (sidelen - 1)) * sidelen + ((int) u & (sidelen - 1));
- pixels[scr++] = tex[idx];
- iz += dizdx;
- uiz += duizdx;
- viz += dvizdx;
- }
- }
- xa += dxdya;
- xb += dxdyb;
- iza += dizdya;
- uiza += duizdya;
- viza += dvizdya;
- y1++;
- }
- }
- public void drawString(String s, int x, int y) {
- char[] ch = s.toCharArray();
- for(int k = 0; k < ch.length; k++) {
- drawChar(ch[k], x, y);
- x += 7;
- }
- }
- public void drawChar(char c, int x, int y) {
- int off = y * width + x;
- int srcoff = 0;
- if(c >= '0' && c <= '9')
- srcoff = c - '0' + 1;
- else if(c >= 'A' && c <= 'Z')
- srcoff = c - 'A' + 11;
- else if(c >= 'a' && c <= 'z')
- srcoff = c - 'a' + 37;
- srcoff *= 7;
- for(int k = 0; k < 13; k++) {
- for (int p = 0; p < 7; p++, off++, srcoff++) {
- if (font[srcoff] != 0)
- pixels[off] = font[srcoff];
- }
- srcoff += fontw - 7;
- off += width - 7;
- }
- }
- public void fillPolygon(int[] x, int[] y, int color) {
- for (int k = 2; k < x.length; k++) {
- fillTriangle(x[0], y[0], x[k - 1], y[k - 1], x[k], y[k], color);
- }
- }
- public void texturedPolygon(int[] x, int[] y, int[] u, int[] v, int[] texture, int sidelen) {
- for (int k = 2; k < x.length; k++) {
- texturedTriangle(x[0], y[0], x[k - 1], y[k - 1], x[k], y[k], u[0],
- v[0], u[k - 1], v[k - 1], u[k], v[k], texture, sidelen);
- }
- }
- public void perspectiveCorrectPolygon(int[] x, int[] y, float[] z, int[] u, int[] v,
- int[] texture, int sidelen) {
- for (int k = 2; k < x.length; k++) {
- perspectiveCorrectTriangle(x[0], y[0], z[0], x[k - 1], y[k - 1],
- z[k - 1], x[k], y[k], z[k], u[0], v[0], u[k - 1], v[k - 1],
- u[k], v[k], texture, sidelen);
- }
- }
- static {
- try {
- BufferedImage fimg = ImageIO.read(RenderSurface.class.getResource("media/font.png"));
- int w = fimg.getWidth();
- int h = fimg.getHeight();
- fontw = w;
- font = new int[w * h];
- fimg.getRGB(0, 0, w, h, font, 0, w);
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement