home games dev
Lewpen.com»Research & Development»3D Graphics»Java 3D Engine»3D Panoramas»Unfolded Panorama

Unfolded Panorama

Instead of rotating the cube the texture can be warped and the cube and view point can remain static

/ Source / House.java

//

import java.awt.*;
import java.applet.*;
import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;



//---- Z3D_Scene -------------------------------------------------------------//

class Z3D_Scene
{
  //- Screen data

  int buf[];
  int w, h;
  
  int clip_x1, clip_y1, clip_x2, clip_y2;
  int cx, cy;
  
  float scale;

  //- Render options

  boolean wireframe = false;
  
  boolean wireframe_changed = false;
  boolean wireframe_new = false;

  //- Traingle data
  
  float tri_x1, tri_y1, tri_z1, tri_u1, tri_v1;
  float tri_x2, tri_y2, tri_z2, tri_u2, tri_v2;
  float tri_x3, tri_y3, tri_z3, tri_u3, tri_v3;

  //- ZN Logo (210x18)
  
  int[] zn_add;
  int[] zn_mul;
  
  //- Orientation

  float rx=0, ry=0, drx=0, dry=0;
  boolean rchanged = true;

  //- 3D Object
  
  int[][] face;
  float[][] point;

  int[] factex;
  int[][] tex;

  float[][] tpoint;
  float[][] spoint;
  
  int numPoints, numFaces;
  


  //---- Scene

  public Z3D_Scene(Applet applet, int[] buf, int w, int h)
  {
    this.w = w;
    this.h = h;
    this.buf = buf;

    clip_x1 = 0;
    clip_y1 = 0;
    clip_x2 = w;
    clip_y2 = h;
    
    cx = w >> 1;
    cy = h >> 1;
    
    scale = w*0.6f;

    //- Create object

    //  Basic object

    point = new float[8][5];
    face = new int[12][4];
    
    numPoints = 8;
    numFaces = 6;
    
    point[0][0] =  1; point[0][1] =  1; point[0][2] =  1;   point[0][3] = 0; point[0][4] = 1; // u & v not done yet!
    point[1][0] =  1; point[1][1] =  1; point[1][2] = -1;   point[1][3] = 0; point[1][4] = 0;
    point[2][0] = -1; point[2][1] =  1; point[2][2] = -1;   point[2][3] = 0; point[2][4] = 0;
    point[3][0] = -1; point[3][1] =  1; point[3][2] =  1;   point[3][3] = 0; point[3][4] = 0;
    point[4][0] =  1; point[4][1] = -1; point[4][2] =  1;   point[4][3] = 0; point[4][4] = 0;
    point[5][0] =  1; point[5][1] = -1; point[5][2] = -1;   point[5][3] = 0; point[5][4] = 0;
    point[6][0] = -1; point[6][1] = -1; point[6][2] = -1;   point[6][3] = 0; point[6][4] = 0;
    point[7][0] = -1; point[7][1] = -1; point[7][2] =  1;   point[7][3] = 0; point[7][4] = 0;
    
    face[0][0] = 3; face[0][1] = 0; face[0][2] = 1; face[0][3] = 2; // 0
    face[1][0] = 2; face[1][1] = 1; face[1][2] = 5; face[1][3] = 6; // 1
    face[2][0] = 3; face[2][1] = 2; face[2][2] = 6; face[2][3] = 7; // 2
    face[3][0] = 6; face[3][1] = 5; face[3][2] = 4; face[3][3] = 7; // 3
    face[4][0] = 0; face[4][1] = 3; face[4][2] = 7; face[4][3] = 4; // 4
    face[5][0] = 1; face[5][1] = 0; face[5][2] = 4; face[5][3] = 5; // 5

    //  Load textures
    
    tex = new int[6][256*256];
    
    int i, j, k;

    for(k=0; k<6; k++)
      for(j=0; j<256; j++)
        for(i=0; i<256; i++)
          tex[k][(j<<8)+i] = (i^j) << (k*2);

    tex[0] = getPixels(applet, "top.jpg", 256, 256);
    tex[1] = getPixels(applet, "front.jpg", 256, 256);
    tex[2] = getPixels(applet, "right.jpg", 256, 256);
    tex[3] = getPixels(applet, "bottom.jpg", 256, 256);
    tex[4] = getPixels(applet, "back.jpg", 256, 256);
    tex[5] = getPixels(applet, "left.jpg", 256, 256);

    //  Working data

    tpoint = new float[8][5];
    spoint = new float[8][5];

    //  ZN Logo

    zn_add = getPixels(applet, "zn_add.jpg", 210, 18);
    zn_mul = getPixels(applet, "zn_mul.jpg", 210, 18);
  }

  //---- getPixels

	private int[] getPixels(Applet applet, String ImageFile, int width, int height)
	{
	  Image TempImage = applet.getImage(applet.getDocumentBase(),ImageFile);
	  
		applet.showStatus("Grabbing Pixels...");
		int TempPixel[]=new int [width*height];

		PixelGrabber pg= new PixelGrabber(TempImage,0,0,width,height,TempPixel,0,width);
		try
		{
			pg.grabPixels();
		}
		catch (InterruptedException e)
		{
		}

		return TempPixel;
	}

  //---- setRotation

  public void addRotation(float rx, float ry)
  {
    drx -= rx*0.01;
    dry += ry*0.01;
    rchanged = true;
  }

  //---- setWireframe

  public void setWireframe(boolean wf)
  {
    wireframe_new = wf;
    wireframe_changed = true;
  }

  //---- render

  public void render()
  {
    if(rchanged)
    {
      rx += drx;
      ry += dry;
      drx = dry = 0;
      rchanged = false;
    }
    else
    {
      return;
    }

    if(wireframe_changed)
    {
      wireframe_changed = false;
      wireframe = wireframe_new;
    }

    //- Clear buffer

    idx3d_Math.clearBuffer(buf, 0x336699);
    
    //- Render object
    
    int i, j;

//    rx = 0.0f;
//    ry += 0.01f;
    
    //  Transform

    float x, y, z;
    idx3d_Matrix m;
    
    m = new idx3d_Matrix();
    m.rotateSelf(rx, 0, 0);
    m.rotateSelf(0, ry, 0);
//    m.shift(0, 0, 2);

    //  Render triangles
    
    scale = w*1/8;
    float hp = 3.14159f * 0.5f;

    //  front    

    transformPoints(m);

    clip_x1 = w*1/4; clip_y1 = h*1/3;
    clip_x2 = w*2/4; clip_y2 = h*2/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //  top

    m.rotate(-hp, 0, 0);
    transformPoints(m);

    clip_x1 = w*1/4; clip_y1 = h*0/3;
    clip_x2 = w*2/4; clip_y2 = h*1/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //  bottom

    m.rotate(hp, 0, 0);
    m.rotate(hp, 0, 0);
    transformPoints(m);

    clip_x1 = w*1/4; clip_y1 = h*2/3;
    clip_x2 = w*2/4; clip_y2 = h*3/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //  left

    m.rotate(-hp, 0, 0);
    m.rotate(0, hp, 0);
    transformPoints(m);

    clip_x1 = w*0/4; clip_y1 = h*1/3;
    clip_x2 = w*1/4; clip_y2 = h*2/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //  back

    m.rotate(0, hp, 0);
    transformPoints(m);

    clip_x1 = w*3/4; clip_y1 = h*1/3;
    clip_x2 = w*4/4; clip_y2 = h*2/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //  right

    m.rotate(0, hp, 0);
    transformPoints(m);

    clip_x1 = w*2/4; clip_y1 = h*1/3;
    clip_x2 = w*3/4; clip_y2 = h*2/3;
    cx = (clip_x1+clip_x2)>>1;
    cy = (clip_y1+clip_y2)>>1;

    for(i=0; i<numFaces; i++) drawSquare(i);

    //- Put ZN logo
    
    int o1 = 0;
    int o2 = w*(h-18);
    int r, g, b, zm, za;

    for(j=0; j<18; j++)
    {
      for(i=0; i<210; i++)
      {
        r = (buf[o2] >> 16)&255;
        g = (buf[o2] >> 8 )&255;
        b = (buf[o2]      )&255;
        
        zm = zn_mul[o1] & 255;
        za = zn_add[o1] & 255;
        
        r = ((r * zm)>>8);
        g = ((g * zm)>>8);
        b = ((b * zm)>>8);
        
        r = ((za>>8) + (r)*(255-za))>>8;
        g = ((za>>8) + (g)*(255-za))>>8;
        b = ((za>>8) + (b)*(255-za))>>8;
        
        if(r > 255) r = 255;
        if(g > 255) g = 255;
        if(b > 255) b = 255;

        if(r < 0) r = 0;
        if(g < 0) g = 0;
        if(b < 0) b = 0;

        buf[o2] = (r<<16)+(g<<8)+(b) + zn_add[o1];

        o1 ++;
        o2 ++;
      }
      
      o2 += w-210;
    }
    
  }  

  void transformPoints(idx3d_Matrix m)
  {
    int i;
    float x, y, z;

    for(i=0; i<numPoints; i++)
    {
      x = point[i][0];
      y = point[i][1];
      z = point[i][2];

  		tpoint[i][0] = x*m.m00 + y*m.m01 + z*m.m02+ m.m03;
  		tpoint[i][1] = x*m.m10 + y*m.m11 + z*m.m12+ m.m13;
    	tpoint[i][2] = x*m.m20 + y*m.m21 + z*m.m22+ m.m23;
	  }
  }

  void renderQuad(int texnum, float[] p1, float[] p2, float[] p3, float[] p4)
  {
    tri_x1 = p1[0];
    tri_y1 = p1[1];
    tri_z1 = p1[2];
    tri_u1 = p1[3];
    tri_v1 = p1[4];
      
    tri_x2 = p2[0];
    tri_y2 = p2[1];
    tri_z2 = p2[2];
    tri_u2 = p2[3];
    tri_v2 = p2[4];
      
    tri_x3 = p3[0];
    tri_y3 = p3[1];
    tri_z3 = p3[2];
    tri_u3 = p3[3];
    tri_v3 = p3[4];
      
    tri_persp(texnum);

    tri_x1 = p3[0];
    tri_y1 = p3[1];
    tri_z1 = p3[2];
    tri_u1 = p3[3];
    tri_v1 = p3[4];
    
    tri_x2 = p4[0];
    tri_y2 = p4[1];
    tri_z2 = p4[2];
    tri_u2 = p4[3];
    tri_v2 = p4[4];
    
    tri_x3 = p1[0];
    tri_y3 = p1[1];
    tri_z3 = p1[2];
    tri_u3 = p1[3];
    tri_v3 = p1[4];
    
    tri_persp(texnum);
  }

  void interpolate(float[] p1, float[] p2, float a, float[] result)
  {
    for(int i=0; i<5; i++)
    {
      result[i] = p1[i] * (1.0f-a) + p2[i] * a;
    }
  }

  void drawSquare(int index)
  {
    float[] p1 = tpoint[face[index][0]];
    float[] p2 = tpoint[face[index][1]];
    float[] p3 = tpoint[face[index][2]];
    float[] p4 = tpoint[face[index][3]];
    
    float[] ip1 = new float[5];
    float[] ip2 = new float[5];
    float[] ip3 = new float[5];
    float[] ip4 = new float[5];
    
    float[] tp1 = new float[5];
    float[] tp2 = new float[5];

    //- Texture co-ords
    
    p1[3] =   0; p1[4] =   0;
    p2[3] = 256; p2[4] =   0;
    p3[3] = 256; p3[4] = 256;
    p4[3] =   0; p4[4] = 256;

    //- Subdivide into 4x4
    
    int i, j;
    
    for(j=0; j<4; j++)
    {
      for(i=0; i<4; i++)
      {
        //  Calculate square
        
        interpolate(p1, p2, (i)*0.25f, tp1);
        interpolate(p4, p3, (i)*0.25f, tp2);
        interpolate(tp1, tp2, (j)*0.25f, ip1);
        
        interpolate(p1, p2, (i+1)*0.25f, tp1);
        interpolate(p4, p3, (i+1)*0.25f, tp2);
        interpolate(tp1, tp2, j*0.25f, ip2);

        interpolate(p1, p2, (i+1)*0.25f, tp1);
        interpolate(p4, p3, (i+1)*0.25f, tp2);
        interpolate(tp1, tp2, (j+1)*0.25f, ip3);

        interpolate(p1, p2, (i)*0.25f, tp1);
        interpolate(p4, p3, (i)*0.25f, tp2);
        interpolate(tp1, tp2, (j+1)*0.25f, ip4);
        
        //  Screen co-ords
        
        ip1[0] = cx + scale * ip1[0] / ip1[2];
        ip1[1] = cy - scale * ip1[1] / ip1[2];

        ip2[0] = cx + scale * ip2[0] / ip2[2];
        ip2[1] = cy - scale * ip2[1] / ip2[2];

        ip3[0] = cx + scale * ip3[0] / ip3[2];
        ip3[1] = cy - scale * ip3[1] / ip3[2];

        ip4[0] = cx + scale * ip4[0] / ip4[2];
        ip4[1] = cy - scale * ip4[1] / ip4[2];
        
        //  render square

        renderQuad(index, ip1, ip2, ip3, ip4);
      }
    }
  }



  //---- tri_col

  public void tri_col(int col)
  {
    
    float t;
    int x, y, y1, y2, x1, x2, o, ti;
    float c1, c2;
    float dc;
    
    //  Don't draw if backfacing
    
    if((tri_x2-tri_x1)*(tri_y3-tri_y1) > (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;
    
    // Sort points
    
    if(tri_y1 > tri_y2) { t=tri_y2; tri_y2=tri_y1; tri_y1=t;  t=tri_x2; tri_x2=tri_x1; tri_x1=t; }
    if(tri_y2 > tri_y3) { t=tri_y3; tri_y3=tri_y2; tri_y2=t;  t=tri_x3; tri_x3=tri_x2; tri_x2=t; }
    if(tri_y1 > tri_y2) { t=tri_y2; tri_y2=tri_y1; tri_y1=t;  t=tri_x2; tri_x2=tri_x1; tri_x1=t; }
    
    // Clip top point to screen and pixel
    
    y1 = (int)tri_y1; if(y1>=h) return; if(y1<0) y1 = 0;
    y2 = (int)tri_y3; if(y2<0) return; if(y2>h) y2 = h;

    c1=0; c2=0;

    for(y=y1-1; y<y2+1; y++)
    {
      if(y >= tri_y1 && y < tri_y3)
      {
        if(y >= tri_y1 && y < tri_y2)
        {
          x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
          x2 = (int)(tri_x1 + (tri_x2-tri_x1) * (y-tri_y1) / (tri_y2-tri_y1));
        }
        else
        {
          x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
          x2 = (int)(tri_x2 + (tri_x3-tri_x2) * (y-tri_y2) / (tri_y3-tri_y2));
        }
        if(x1 > x2)
        {
          ti = x2; x2 = x1; x1 = ti;
          t = c2; c2 = c1; c1 = t;
        }
        if(x1 < 0) x1 = 0;
        if(x2 > w) x2 = w;
    
        if(x2 > x1) {
          dc = (c2-c1)/(x2-x1);
    
          o = y*w + x1;
    
          for(x = x1; x < x2; x ++) buf[o++] = col;
        }
          
      }
    }
    
  }


  //---- tri_tex

  public void tri_tex(int texnum)
  {
    int[] tex = this.tex[texnum];

    float t;
    int x, y;
    
    int x1, x2, y1, y2;

    int o, ti;
    float u1, v1, u2, v2;
    float du, dv;
    
    //  Don't draw if backfacing
    
    if((tri_x2-tri_x1)*(tri_y3-tri_y1) > (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;
    
    // Sort points
    
    if(tri_y1 > tri_y2)
    {
      t=tri_x2; tri_x2=tri_x1; tri_x1=t;
      t=tri_y2; tri_y2=tri_y1; tri_y1=t;
      t=tri_u2; tri_u2=tri_u1; tri_u1=t;
      t=tri_v2; tri_v2=tri_v1; tri_v1=t;
    }
    if(tri_y2 > tri_y3)
    {
      t=tri_x3; tri_x3=tri_x2; tri_x2=t;
      t=tri_y3; tri_y3=tri_y2; tri_y2=t;
      t=tri_u3; tri_u3=tri_u2; tri_u2=t;
      t=tri_v3; tri_v3=tri_v2; tri_v2=t;
    }
    if(tri_y1 > tri_y2)
    {
      t=tri_x2; tri_x2=tri_x1; tri_x1=t;
      t=tri_y2; tri_y2=tri_y1; tri_y1=t;
      t=tri_u2; tri_u2=tri_u1; tri_u1=t;
      t=tri_v2; tri_v2=tri_v1; tri_v1=t;
    }
    
    // Clip top point to screen and pixel
    
    y1 = (int)tri_y1; if(y1>=h) return; if(y1<0) y1 = 0;
    y2 = (int)tri_y3; if(y2<0) return; if(y2>h) y2 = h;
    
    u1 = 0; v1 = 0; u2 = 0; v2 = 0;

    for(y=y1-1; y<y2+1; y++)
    {
      if(y >= tri_y1 && y < tri_y3)
      {
        if(y >= tri_y1 && y < tri_y2)
        {
          x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
          x2 = (int)(tri_x1 + (tri_x2-tri_x1) * (y-tri_y1) / (tri_y2-tri_y1));

          u1 = (tri_u1 + (tri_u3-tri_u1) * (y-tri_y1) / (tri_y3-tri_y1));
          u2 = (tri_u1 + (tri_u2-tri_u1) * (y-tri_y1) / (tri_y2-tri_y1));

          v1 = (tri_v1 + (tri_v3-tri_v1) * (y-tri_y1) / (tri_y3-tri_y1));
          v2 = (tri_v1 + (tri_v2-tri_v1) * (y-tri_y1) / (tri_y2-tri_y1));
        }
        else
        {
          x1 = (int)(tri_x1 + (tri_x3-tri_x1) * (y-tri_y1) / (tri_y3-tri_y1));
          x2 = (int)(tri_x2 + (tri_x3-tri_x2) * (y-tri_y2) / (tri_y3-tri_y2));

          u1 = (tri_u1 + (tri_u3-tri_u1) * (y-tri_y1) / (tri_y3-tri_y1));
          u2 = (tri_u2 + (tri_u3-tri_u2) * (y-tri_y2) / (tri_y3-tri_y2));

          v1 = (tri_v1 + (tri_v3-tri_v1) * (y-tri_y1) / (tri_y3-tri_y1));
          v2 = (tri_v2 + (tri_v3-tri_v2) * (y-tri_y2) / (tri_y3-tri_y2));
        }
        if(x1 > x2)
        {
          ti = x2; x2 = x1; x1 = ti;
          t  = u2; u2 = u1; u1 = t;
          t  = v2; v2 = v1; v1 = t;
        }
        if(x1 < 0) x1 = 0;
        if(x2 > w) x2 = w;
    
        if(x2 > x1) {
          du = (u2-u1)/(x2-x1);
          dv = (v2-v1)/(x2-x1);
    
          o = y*w + x1;
    
          for(x = x1; x < x2; x ++)
          {
            ti = (((int)v1)<<8) + ((int)u1);
            
            ti = (int)u1;
            ti = (ti<<16)+(ti<<8)+ti;
            buf[o++] = ti;//tex[ti];
            u1 += du;
            v1 += dv;
          }
        }
          
      }
    }
    
  }



  public void tri_persp(int texnum)
  {
    if(tri_z1 < 0) return;
    if(tri_z2 < 0) return;
    if(tri_z3 < 0) return;

    int[] tex = this.tex[texnum];
    
    tri_u1 = 256-tri_u1;
    tri_u2 = 256-tri_u2;
    tri_u3 = 256-tri_u3;

    int i, j;

    //  Don't draw if backfacing
    
//    if((tri_x2-tri_x1)*(tri_y3-tri_y1) < (tri_x3-tri_x1)*(tri_y2-tri_y1)) return;

    //- Sort points

    float t;

    if(tri_y2 < tri_y1)
    {
        t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
        t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
        t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
        t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
        t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
    }

    if(tri_y3 < tri_y2)
    {
        t = tri_x2; tri_x2 = tri_x3; tri_x3 = t;
        t = tri_y2; tri_y2 = tri_y3; tri_y3 = t;
        t = tri_z2; tri_z2 = tri_z3; tri_z3 = t;
        t = tri_u2; tri_u2 = tri_u3; tri_u3 = t;
        t = tri_v2; tri_v2 = tri_v3; tri_v3 = t;
    }

    if(tri_y2 < tri_y1)
    {
        t = tri_x1; tri_x1 = tri_x2; tri_x2 = t;
        t = tri_y1; tri_y1 = tri_y2; tri_y2 = t;
        t = tri_z1; tri_z1 = tri_z2; tri_z2 = t;
        t = tri_u1; tri_u1 = tri_u2; tri_u2 = t;
        t = tri_v1; tri_v1 = tri_v2; tri_v2 = t;
    }
  
    //- Divide by z to do perspective correction

    tri_u1 /= tri_z1; tri_u2 /= tri_z2; tri_u3 /= tri_z3;
    tri_v1 /= tri_z1; tri_v2 /= tri_z2; tri_v3 /= tri_z3;

    tri_z1 = 1.0f/tri_z1; tri_z2 = 1.0f/tri_z2; tri_z3 = 1.0f/tri_z3;
  
    //- Work out deltas along edges

    float dx12 = (tri_x2-tri_x1)/(tri_y2-tri_y1), dx23 = (tri_x3-tri_x2)/(tri_y3-tri_y2), dx13 = (tri_x3-tri_x1)/(tri_y3-tri_y1);
    float dz12 = (tri_z2-tri_z1)/(tri_y2-tri_y1), dz23 = (tri_z3-tri_z2)/(tri_y3-tri_y2), dz13 = (tri_z3-tri_z1)/(tri_y3-tri_y1);
    float du12 = (tri_u2-tri_u1)/(tri_y2-tri_y1), du23 = (tri_u3-tri_u2)/(tri_y3-tri_y2), du13 = (tri_u3-tri_u1)/(tri_y3-tri_y1);
    float dv12 = (tri_v2-tri_v1)/(tri_y2-tri_y1), dv23 = (tri_v3-tri_v2)/(tri_y3-tri_y2), dv13 = (tri_v3-tri_v1)/(tri_y3-tri_y1);
  
    //- Round to pixel and clip to top & bottom of screen

    int y1 = (int)tri_y1; if(y1 < tri_y1) y1++;
    int y2 = (int)tri_y2; if(y2 < tri_y2) y2++;
    int y3 = (int)tri_y3; if(y3 < tri_y3) y3++;

    if(y1 < clip_y1) y1 = clip_y1;
    if(y2 < clip_y1) y2 = clip_y1;
    if(y3 < clip_y1) y3 = clip_y1;

    if(y1 > clip_y2) y1 = clip_y2;
    if(y2 > clip_y2) y2 = clip_y2;
    if(y3 > clip_y2) y3 = clip_y2;

    if(y3 <= y1) return;

    //- Calculate horizontal and vertical deltas for parameters

    float d = (tri_x3-tri_x1)*(tri_y2-tri_y1) - (tri_y3-tri_y1)*(tri_x2-tri_x1);

    float dzx = ( (tri_y2-tri_y1)*(tri_z3-tri_z1) + (tri_y1-tri_y3)*(tri_z2-tri_z1) ) / d;
    float dzy = ( (tri_x1-tri_x2)*(tri_z3-tri_z1) + (tri_x3-tri_x1)*(tri_z2-tri_z1) ) / d;

    float dux = ( (tri_y2-tri_y1)*(tri_u3-tri_u1) + (tri_y1-tri_y3)*(tri_u2-tri_u1) ) / d;
    float duy = ( (tri_x1-tri_x2)*(tri_u3-tri_u1) + (tri_x3-tri_x1)*(tri_u2-tri_u1) ) / d;

    float dvx = ( (tri_y2-tri_y1)*(tri_v3-tri_v1) + (tri_y1-tri_y3)*(tri_v2-tri_v1) ) / d;
    float dvy = ( (tri_x1-tri_x2)*(tri_v3-tri_v1) + (tri_x3-tri_x1)*(tri_v2-tri_v1) ) / d;

    //- See if we need to flip triangle horizontally
  
  	boolean side13onleft = dx13 < dx12;
  
    //- Draw top of triangle

    float xa, xb, dxa, dxb;

    if(side13onleft)
    {
      xa = tri_x1 + dx13 * (y1-tri_y1);
   	  xb = tri_x1 + dx12 * (y1-tri_y1);
   	  dxa = dx13;
   	  dxb = dx12;
   	}
	  else
	  {
   	  xa = tri_x1 + dx12 * (y1-tri_y1);
      xb = tri_x1 + dx13 * (y1-tri_y1);
   	  dxa = dx12;
   	  dxb = dx13;
  	}
  
    float zl = tri_z1 - tri_x1*dzx + (y1-tri_y1)*dzy;
    float ul = tri_u1 - tri_x1*dux + (y1-tri_y1)*duy;
    float vl = tri_v1 - tri_x1*dvx + (y1-tri_y1)*dvy;

    for(j=y1; j<y2; j++)
    {
      int xai = (int)xa; if(xai < xa) xai++;
      int xbi = (int)xb; if(xbi < xb) xbi++;
  
  		if(xai < clip_x1) xai = clip_x1;
  		if(xbi < clip_x1) xbi = clip_x1;
      if(xai > clip_x2) xai = clip_x2;
  		if(xbi > clip_x2) xbi = clip_x2;
  
      float z = zl + xai*dzx;
      float u = ul + xai*dux;
      float v = vl + xai*dvx;
  
      int o = j*w+xai;

      for(i=xai; i<xbi; i++)
      {
        buf[o++] = tex[ ( (((int)(v/z))<<8) + ((int)(u/z)) ) & 0xFFFF ];//(((int)u)<<16)+(((int)v)<<8);
        z += dzx;
  			u += dux;
  			v += dvx;
      }
  
      xa += dxa; xb += dxb;

      zl += dzy;
      ul += duy;
      vl += dvy;
    }
  
    //- Draw bottom of triangle
  
    if(side13onleft)
    {
      xb = tri_x2 + dx23 * (y2-tri_y2);
  	  dxb = dx23;
  	}
	  else
	  {
      xa = tri_x2 + dx23 * (y2-tri_y2);
  	  dxa = dx23;
  	}
  
    for(j=y2; j<y3; j++)
    {
      int xai = (int)xa; if(xai < xa) xai++;
      int xbi = (int)xb; if(xbi < xb) xbi++;
  
  		if(xai < clip_x1) xai = clip_x1;
  		if(xbi < clip_x1) xbi = clip_x1;
  		if(xai > clip_x2) xai = clip_x2;
  		if(xbi > clip_x2) xbi = clip_x2;
  
      float z = zl + xai*dzx;
      float u = ul + xai*dux;
      float v = vl + xai*dvx;

      int o = j*w+xai;
        
      for(i=xai; i<xbi; i++)
      {
        buf[o++] = tex[ ( (((int)(v/z))<<8) + ((int)(u/z)) ) & 0xFFFF ];//(((int)u)<<16)+(((int)v)<<8);
        z += dzx;
  			u += dux;
  			v += dvx;
      }
  
      xa += dxa; xb += dxb;
  
      zl += dzy;
      ul += duy;
      vl += dvy;
    }
  
  }


}



//---- House -----------------------------------------------------------------//

public class House extends tinyptc
{
  //- Data

  int rx, ry;

  Z3D_Scene scene;

  //- Mouse data

  int mouse_x = 0, mouse_y = 0;
  int mouse_oldx = 0, mouse_oldy = 0;
  boolean mouse_drag = true;
  int mouse_changex = 0, mouse_changey = 0;



  //- Main code

  public void main(int width, int height)
  {
    int size = width * height;
    int buf[] = new int[size];
    int seed = 0x12345;

    scene = new Z3D_Scene(this, buf, width, height);
    
    while (true)
    {
      scene.addRotation(mouse_changey, mouse_changex);
      mouse_changex = 0;
      mouse_changey = 0;
      scene.render();
      update(buf);

//      while(mouse_changex == 0 && mouse_changey == 0);
    }
  }






  public boolean mouseDown(Event evt, int x, int y)
  {
    mouse_oldx = x;
    mouse_oldy = y;
    mouse_x = x;
    mouse_y = y;
    mouse_drag = true;

    return true;
  }


  
  public boolean mouseDrag(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;

    mouse_changex += mouse_x-mouse_oldx;    
    mouse_changey += mouse_y-mouse_oldy;    

    mouse_oldx = x;
    mouse_oldy = y;

    return true;
  }



  public boolean mouseUp(Event evt, int x, int y)
  {
    mouse_drag = false;

    return true;
  }
  

}

Comments

Related Articles

This is a barebones renderer for one object, with a software solid triangle rasteriser

Placing the viewpoint inside the cube and making the faces of the cube textured

Sponsored Links

Toys & Games:

Doggie Doo
Nerf Vortex
Monster High
Lagoona Hydration Station
Milky Bunny
Moshling Tree House
Lego Ninja Go Fire Temple
Fireman Sam Pontypandy Rescue
Rock Elmo
Star Wars Ultimate Force Lightsaber

Games

The Dodge Game
Flatspace

2-Player Games:

Quake 2D
Meteora

Puzzle Games:

Mini Tetris
Sudoku Solver

Development

3D Graphics:

3D Graphics Articles
WebGL Examples
Flash 3D Engine
Java 3D Engine

Development:

Programming Articles
Animation Demos
Game Development Examples

Links

iBuddy Social Network
Local Legends Football
PHP Charts & Graphs
CubeLogix Studios