public void render(int offset, int left, int right) { ShadedSurface texture = (ShadedSurface) currentTexture; float u = SCALE * a.getDotProduct(viewPos); float v = SCALE * b.getDotProduct(viewPos); float z = c.getDotProduct(viewPos); float du = INTERP_SIZE * SCALE * a.x; float dv = INTERP_SIZE * SCALE * b.x; float dz = INTERP_SIZE * c.x; int nextTx = (int) (u / z); int nextTy = (int) (v / z); int depth = (int) (w * z); int dDepth = (int) (w * c.x); int x = left; while (x <= right) { int tx = nextTx; int ty = nextTy; int maxLength = right - x + 1; if (maxLength > INTERP_SIZE) { u += du; v += dv; z += dz; nextTx = (int) (u / z); nextTy = (int) (v / z); int dtx = (nextTx - tx) >> INTERP_SIZE_BITS; int dty = (nextTy - ty) >> INTERP_SIZE_BITS; int endOffset = offset + INTERP_SIZE; while (offset < endOffset) { if (zBuffer.checkDepth(offset, (short) (depth >> SCALE_BITS))) { doubleBufferData[offset] = texture.getColor(tx >> SCALE_BITS, ty >> SCALE_BITS); } offset++; tx += dtx; ty += dty; depth += dDepth; } x += INTERP_SIZE; } else { // variable interpolation size int interpSize = maxLength; u += interpSize * SCALE * a.x; v += interpSize * SCALE * b.x; z += interpSize * c.x; nextTx = (int) (u / z); nextTy = (int) (v / z); // make sure tx, ty, nextTx, and nextTy are // all within bounds tx = checkBounds(tx, texture.getWidth()); ty = checkBounds(ty, texture.getHeight()); nextTx = checkBounds(nextTx, texture.getWidth()); nextTy = checkBounds(nextTy, texture.getHeight()); int dtx = (nextTx - tx) / interpSize; int dty = (nextTy - ty) / interpSize; int endOffset = offset + interpSize; while (offset < endOffset) { if (zBuffer.checkDepth(offset, (short) (depth >> SCALE_BITS))) { doubleBufferData[offset] = texture.getColor(tx >> SCALE_BITS, ty >> SCALE_BITS); } offset++; tx += dtx; ty += dty; depth += dDepth; } x += interpSize; } } }
public void parseLine(String line) throws IOException, NumberFormatException, NoSuchElementException { StringTokenizer tokenizer = new StringTokenizer(line); String command = tokenizer.nextToken(); if (command.equals("v")) { // create a new vertex vertices.add( new Vector3D( Float.parseFloat(tokenizer.nextToken()), Float.parseFloat(tokenizer.nextToken()), Float.parseFloat(tokenizer.nextToken()))); } else if (command.equals("f")) { // create a new face (flat, convex polygon) List currVertices = new ArrayList(); while (tokenizer.hasMoreTokens()) { String indexStr = tokenizer.nextToken(); // ignore texture and normal coords int endIndex = indexStr.indexOf('/'); if (endIndex != -1) { indexStr = indexStr.substring(0, endIndex); } currVertices.add(getVector(indexStr)); } // create textured polygon Vector3D[] array = new Vector3D[currVertices.size()]; currVertices.toArray(array); TexturedPolygon3D poly = new TexturedPolygon3D(array); // set the texture ShadedSurface.createShadedSurface( poly, currentMaterial.texture, lights, ambientLightIntensity); // add the polygon to the current group currentGroup.addPolygon(poly); } else if (command.equals("g")) { // define the current group if (tokenizer.hasMoreTokens()) { String name = tokenizer.nextToken(); currentGroup = new PolygonGroup(name); } else { currentGroup = new PolygonGroup(); } object.addPolygonGroup(currentGroup); } else if (command.equals("mtllib")) { // load materials from file String name = tokenizer.nextToken(); parseFile(name); } else if (command.equals("usemtl")) { // define the current material String name = tokenizer.nextToken(); currentMaterial = (Material) materials.get(name); if (currentMaterial == null) { System.out.println("no material: " + name); } } else { // unknown command - ignore it } }