HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Real Time 3D Graphics:
Using Java and Microsoft's DirectX Libraries"
Vol. 2, Issue 10, p. 22

	

Listing 1.  SimData.java 

import com.ms.com.*; 
import com.ms.awt.*; 
import com.ms.awt.peer.*; 
import com.ms.directX.*; 

public class SimData 
{ 
  D3dVector dir = new D3dVector(); 
  public Direct3dRM d3drm; 
  public Direct3dRMFrame scene; 
  public Direct3dRMFrame camera; 
  public Direct3dRMDevice dev; 
  public Direct3dRMViewport view; 
  public Direct3dRMFrame cube_frame_1; 
  public Direct3dRMFrame cube_frame_2; 
  public float rx,ry,rz,rtheta; 
  public int keydown; 
} 

Listing 2.  AnimFrame.java
 
import java.awt.*; 
import java.util.Vector; 
import com.ms.com.*; 
import com.ms.directX.*; 

public class AnimFrame implements DirectXConstants, ILoadTextureCallback { 
  Direct3d d; 
  Direct3dRM d3drm; 
  DirectDrawClipper ddclipper; 
  Direct3dRMMeshBuilder builder; 
  Direct3dRMTexture[] textures = new Direct3dRMTexture[2]; 
  int textureCount; 
  SimData info; 
  Animator f = null; 

  protected void finalize() { 
    for ( int i = 0; i < 2; i++ ) 
      if ( textures[i] != null ) 
        ComLib.release(textures[i]); 

    ComLib.release(info.cube_frame_1); 
    ComLib.release(info.cube_frame_2); 
    ComLib.release(builder); 
    ComLib.release(info.camera); 
    ComLib.release(info.scene); 
    ComLib.release(info.view); 
    ComLib.release(ddclipper); 
    ComLib.release(info.dev); 
    ComLib.release(d); 
    ComLib.release(d3drm); 
  } 

  public Animator startDirect(Component c) { 
    info = new SimData(); 
    d3drm = new Direct3dRM(); 
    info.d3drm = d3drm; 

    ddclipper = new DirectDrawClipper(); 
    ddclipper.setComponent(c); 

    d = new Direct3d(); 
    _Guid g = d.findDeviceForColorModel(D3DCOLOR_MONO, 0); 
    info.dev = d3drm.createDeviceFromClipper(ddclipper, g, 240, 180); 

    switch (d.systemBpp()) { // from Microsoft examples: 
    case 1: 
      info.dev.setShades(4); 
      d3drm.setDefaultTextureShades(4); 
      break; 
    case 16: 
      info.dev.setShades(32); 
      d3drm.setDefaultTextureColors(64); 
      d3drm.setDefaultTextureShades(32); 
      info.dev.setDither(0); 
      break; 
    case 24: 
    case 32: 
      info.dev.setShades(256); 
      d3drm.setDefaultTextureColors(64); 
      d3drm.setDefaultTextureShades(256); 
      info.dev.setDither(0); 
      break; 
    default: 
      info.dev.setShades(1); 
      info.dev.setDither(0); 
      d3drm.setDefaultTextureShades(1); 
      break; 
    } 

    info.dev.setQuality(D3DRMRENDER_UNLITFLAT); 
    info.dev.setTextureQuality( D3DRMTEXTURE_NEAREST ); 

    info.scene = d3drm.createFrame(null); // create scene: 

    // cube # 1 
    info.cube_frame_1 = d3drm.createFrame(info.scene); 
    info.cube_frame_1.setRotation(info.scene, 0.1F, 1.0F, 0.3F, 0.05F); 
    info.cube_frame_1.setPosition(info.scene, 0.0F, 0.0F, 10.0F); 
    builder = d3drm.createMeshBuilder(); 
    builder.loadFromFileByPos("ncube1.x", 0, 0, (ILoadTextureCallback)this, null); 
    builder.setColorRGB(0.8F, 0.8F, 0.8F); 
    info.cube_frame_1.addVisualMeshBuilder(builder); 

    // cube # 2 
    info.cube_frame_2 = d3drm.createFrame(info.scene); 
    info.cube_frame_2.setRotation(info.scene, 0.14F, 1.0F, 0.2F, 0.07F); 
    info.cube_frame_2.setPosition(info.scene, 7.0F, 0.0F, 0.0F); 
    builder = d3drm.createMeshBuilder(); 
    builder.loadFromFileByPos("ncube2.x", 0, 0, (ILoadTextureCallback)this, null); 
    builder.setColorRGB(0.8F, 0.8F, 0.8F); 
    info.cube_frame_2.addVisualMeshBuilder(builder); 

    info.camera = d3drm.createFrame(info.scene); 
    info.camera.setPosition(info.scene, 0.0F, 0.0F, -14.0F); 

    info.view = d3drm.createViewport(info.dev, info.camera, 0, 0, 
                                     info.dev.getWidth(), 
                                     info.dev.getHeight()); 
    info.view.setBack(5000.0F); 

    f = new Animator(Thread.NORM_PRIORITY, info); 
    return f; 
  } 

  public Direct3dRMTexture callbackLoadTexture(String name, IUnknown a) { 
    return textures[textureCount++] = d3drm.loadTexture(name); 
  } 
} 

Listing 3.  Animator.java
 
import java.awt.*; 
import java.applet.*; 
import com.ms.com.*; 
import com.ms.awt.*; 
import com.ms.awt.peer.*; 
import com.ms.directX.*; 

class Animator implements Runnable, DirectXConstants 
{ 
  private Thread work; // work thread 
  private boolean running = true; 

  public SimData win; 

  private D3dVector pos; 
  private D3dVector dir; 
  private D3dVector up; 
  private D3dVector right; 
  private D3dVector zaxis; 

  // for cube positions: 
  private float x1[] = new float[3000]; 
  private float z1[] = new float[3000]; 
  private float x2[] = new float[3000]; 
  private float z2[] = new float[3000]; 
  private int index = 0; 

  public Animator(int p, SimData info) { 
    for (int i=0; i<3000; i++) { 
      float theta = ((float)i)*6.28f / 3000.0f; 
      x1[i] = (float)(10.0f*Math.sin(theta+0.25)); 
      z1[i] = (float)(10.0f*Math.cos(theta+0.25)); 
      x2[i] = (float)(4.0f*Math.sin(2.0f*theta)); 
      z2[i] = (float)(4.0f*Math.cos(2.0f*theta)); 
    } 

    win = info; 
                 
    work = new Thread(this); 
    work.setPriority(p); 

    pos   = new D3dVector(); 
    dir   = new D3dVector(); 
    up    = new D3dVector(); 
    right = new D3dVector(); 
  } 

  public void run() { 
    while(running) { 
      Render(); 
      // update the positions of the two cubes: 
      win.cube_frame_1.setPosition(win.scene, x1[index], 0.0F, z1[index]); 
      win.cube_frame_2.setPosition(win.scene, x2[index], 0.0F, z2[index]); 
      index++; 
      if (index>=3000)  index=0; 
      // adjust camera viewing rotation and position: 
      win.camera.getOrientation(win.scene, dir, up); 
      win.camera.getPosition(win.scene, pos); 
      win.d3drm.vectorCrossProduct(right, up, dir); 
      if (win.keydown == 0 ) { // stop rotation 
        win.rtheta = 0.0F; 
        win.ry     = 0.0F; 
        win.rx     = 0.0F; 
        win.rz     = 0.0F; 
      } 
      win.camera.setRotation(win.scene, win.rx, win.ry, win.rz, win.rtheta); 
      if ((win.keydown  & 0xC) > 0) { 
        pos.x += win.dir.x; 
        pos.z += win.dir.z; 
      } 
      if ((win.keydown & 0x40) > 0) { // up 
        pos.y += 0.1f; 
      } 
      if ((win.keydown & 0x80) > 0) { // down 
        pos.y -= 0.1f; 
      } 
      win.camera.setPosition(win.scene, pos.x,pos.y,pos.z); 
    } 
  } 
         
  public void stop() { running = false; } 
         
  public void start() { running = true; work.start(); } 

  private void Render() { 
    win.scene.move(1.0F); 
    win.view.clear(); 
    win.view.render(win.scene); 
    win.dev.update(); 
  } 
} 

Listing 4.  test.java
 
import java.awt.*; 
import java.applet.*; 
import com.ms.com.*; 
import com.ms.directX.*; 

public class test extends Applet 
{ 
  Animator anim = null; 
  AnimFrame vFrame = null; 
  D3dVector dir = new D3dVector(); 
  D3dVector up = new D3dVector(); 
  D3dVector right = new D3dVector(); 
         
  public static void main(String args[]) { 
    test applet = new test(); 

    Frame frame = new Frame("Java/Direct3D Demo"); 

    frame.setSize(240,180); 
    frame.add("Center", applet); 

    frame.show(); 
    applet.init(); 
    applet.start(); 
  } 

  public void init() { 
    vFrame = new AnimFrame(); 
    anim = vFrame.startDirect(this); 
    requestFocus(); 
  } 

  public void start() { anim.start(); } 

  public void stop() { anim.stop(); } 

  public boolean keyUp(Event e, int key) { 
    switch(key) { 
      case Event.UP: 
        anim.win.keydown &= ~0x1; 
        break; 
      case Event.DOWN: 
        anim.win.keydown &= ~0x2; 
        break; 

      case 'a': 
      case 'A': 
        anim.win.keydown &= ~0x4; 
        anim.win.dir.x = 0; 
        anim.win.dir.z = 0; 
        break; 
      case 'z': 
      case 'Z': 
        anim.win.keydown &= ~0x8; 
        anim.win.dir.x = 0; 
        anim.win.dir.z = 0; 
        break; 
      case 'q': 
      case 'Q': 
      case 27: // escape 
 System.exit(0); 
 break; 

      case Event.LEFT: 
        anim.win.keydown &= ~0x10; 
        break; 
      case Event.RIGHT: 
        anim.win.keydown &= ~0x20; 
        break; 
    case 'u': 
        anim.win.keydown &= ~0x40; 
        break; 
    case 'd': 
        anim.win.keydown &= ~0x80; 
        break; 

      } 

    return true; 
  } 

  public boolean keyDown(Event e, int key) { 
    anim.win.camera.getOrientation(anim.win.scene, dir, up); 
    anim.win.d3drm.vectorCrossProduct(right, up, dir); 

    switch(key) { 
      case Event.UP: 
        anim.win.keydown |= 0x1; 
        anim.win.rtheta = 0.01F;  // speed to rotate 
        anim.win.rx     = right.x;  // axis to rotate about 
        anim.win.rz     = right.z; 
        break; 

      case Event.DOWN: 
        anim.win.keydown |= 0x2; 
        anim.win.rtheta = 0.01F; 
        anim.win.rx     = -right.x; 
        anim.win.rz     = -right.z; 
        break; 
                  
      case 'a': 
      case 'A': 
        anim.win.keydown |= 0x4; 
        anim.win.dir.x = dir.x * 0.2F; 
        anim.win.dir.z = dir.z * 0.2F; 
        break; 

      case 'z': 
      case 'Z': 
        anim.win.keydown |= 0x8; 
        anim.win.dir.x = dir.x * -0.2F; 
        anim.win.dir.z = dir.z * -0.2F; 
        break; 

      case 'u': 
      case 'U': 
        anim.win.keydown |= 0x40; 
        anim.win.dir.y = dir.y * -0.2F; // move up 
        break; 

      case 'd': 
      case 'D': 
        anim.win.keydown |= 0x80; 
        anim.win.dir.y = dir.y * 0.2F; // move down 
        break; 

      case Event.LEFT: 
        anim.win.keydown |= 0x10; 
        anim.win.rtheta = 0.01F; 
        anim.win.ry     = -up.y; 
        break; 

      case Event.RIGHT: 
        anim.win.keydown |= 0x20; 
        anim.win.rtheta = 0.01F; 
        anim.win.ry     = up.y; 
        break; 
      } 
    return true; 
  } 
}

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.