Software mode demo
From JPCT
Software mode demo
Details
This is a bare minimum software renderer example... This is nothing fancy, but may be helpful for first time jPCT users or anybody interested in using the jPCT software renderer mode to design their 3D application.
Screen shot
Source code
import java.awt.*; import java.awt.event.*; import java.util.Random; import java.util.concurrent.TimeUnit; import javax.swing.*; import com.threed.jpct.*; /** * A bare bones jPCT software mode application. * @author 'words' - jPCT.net */ @SuppressWarnings("serial") public class Engine extends JFrame implements KeyEventDispatcher, MouseListener, MouseMotionListener { // "Engine" variables... private final Graphics graphics; private FrameBuffer buffer; private final World world; private boolean keepAlive = false; private int mouseX = -1; private int mouseY = -1; private int frameCount = 0; // Program content variables... private Object3D cube; private Random random = new Random(); static { Logger.setLogLevel(Logger.ERROR); /* * Configure the 3D engine (jPCT) settings. * http://www.jpct.net/doc/com/threed/jpct/Config.html */ // When using the software renderer on a multi core setup, it's a good idea to use all cores (or at least some of them) to speed up rendering. // To do so, set Config.useMultipleThreads to true before instantiating the frame buffer. // By default, jPCT will use four cores, which matches a quad core cpu. If the setup that runs the application uses less cores, it's advised to adjust this value before instantiating the frame buffer. // http://www.jpct.net/wiki/index.php?title=Multithreading#The_threading_framework Config.useMultipleThreads = Runtime.getRuntime().availableProcessors() > 1; // Dynamic load balancing usually is the better choice. // It's not enable by default simply because it can cause small artifacts in combination with the texel filtering that jPCT uses (some pixels may flicker from time to time). Config.loadBalancingStrategy = 1; // Usually, one have to call build() on all objects that have to be rendered. Config.autoBuild = true; // The maximum size of the VisList. Config.maxPolysVisible = 32000; // 32k /* * Submit a garbage collection to the virtual machine. */ Runtime.getRuntime().runFinalization(); Runtime.getRuntime().gc(); } public static void main(String[] args) { new Engine(); } public Engine() { this.setTitle("jPCT " + Config.getVersion()); this.setPreferredSize(new Dimension(320, 320)); this.setBackground(Color.BLACK); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setSize(320, 320); this.setResizable(true); this.setLocationRelativeTo(null); this.setVisible(true); this.graphics = getGraphics(); /* * Bind the hardware input listeners. */ KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); this.addWindowListener(new WindowExitListener(this)); this.addMouseListener(this); this.addMouseMotionListener(this); /* * Initialize a "re-sizable" frame buffer. */ this.buffer = new FrameBuffer(320, 320, FrameBuffer.SAMPLINGMODE_NORMAL); buffer.disableRenderer(IRenderer.RENDERER_OPENGL); buffer.enableRenderer(IRenderer.RENDERER_SOFTWARE); buffer.optimizeBufferAccess(); this.addComponentListener(new ComponentListener() { @Override public void componentResized(ComponentEvent e) { int w = getWidth(); int h = getHeight(); buffer = new FrameBuffer(w, h, FrameBuffer.SAMPLINGMODE_NORMAL); buffer.refresh(); } @Override public void componentHidden(ComponentEvent e) { } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentShown(ComponentEvent e) { } }); // Initialize worlds this.world = new World(); world.setAmbientLight(85, 85, 85); // Overall world brightness // Create the cube object this.cube = Primitives.getCube(5); world.addObject(cube); // Move camera Camera cam = world.getCamera(); cam.moveCamera(Camera.CAMERA_MOVEOUT, 30); cam.moveCamera(Camera.CAMERA_MOVEUP, 15); cam.lookAt(cube.getTransformedCenter()); cam.setFOV(1.5f); /* * Run the program. */ keepAlive = true; execute(); } @Override public void mousePressed(MouseEvent e) { int button = e.getButton(); if (button == 1) { System.out.println("Mouse -> L click @ " + mouseX + "," + mouseY); } if (button == 3) { System.out.println("Mouse -> R click @ " + mouseX + "," + mouseY); } } @Override public void mouseReleased(MouseEvent e) { int button = e.getButton(); if (button == 1) { System.out.println("Mouse -> left button released"); } if (button == 3) { System.out.println("Mouse -> right button released"); } } @Override public void mouseMoved(MouseEvent e) { this.mouseX = e.getX(); this.mouseY = e.getY(); } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { } @Override public boolean dispatchKeyEvent(KeyEvent e) { if (e.getID() == KeyEvent.KEY_RELEASED && e.getKeyCode() == KeyEvent.VK_ESCAPE) { keepAlive = false; } return true; } private void execute() { World.setDefaultThread(Thread.currentThread()); long lastSecond = 0L; while (keepAlive) { long currentTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); // Reset the frame counter. if (lastSecond < currentTime - 1000) { lastSecond = currentTime; setTitle("FPS: " + frameCount); frameCount = 0; // Re-color the cube cube.setAdditionalColor(random.nextInt(255), random.nextInt(255), random.nextInt(255)); } // Rotate the cube cube.rotateZ(0.01f * random.nextFloat()); // Clear the previous frame. buffer.clear(); /* * Draw the new frame. */ frameCount++; world.renderScene(buffer); world.draw(buffer); buffer.update(); buffer.display(graphics); } /* * Terminate the program. */ System.exit(0); } /** * Listen for the window exit event and use exit prompt. */ public class WindowExitListener extends WindowAdapter { private final JFrame frame; public WindowExitListener(final JFrame frame) { this.frame = frame; } @Override public void windowClosing(final WindowEvent e) { frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); String ObjButtons[] = { "Yes", "No" }; int result = JOptionPane.showOptionDialog(null, "Exit jPCT + " + Config.getVersion() + " ?", "Confirm Exit", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, ObjButtons, ObjButtons[1]); if (result == JOptionPane.YES_OPTION) { System.exit(0); } } } }