DEar Vincent,

        Thank you for you help!

        But I think I should talk about my problem that I'm facing. I'm
writing a 3D maze applet. I need to do the texture mapping on the walls.
The far walls will darker than the near walls. I can put the GIF picture
on the walls. But when I use the JPEG instead. Exception came out and
nothing to see on the applet. I think the problem is in the color model. 

The following is the class to read the image, reference from a book:

public class ImageBytes implements ImageConsumer {
        public int              width, height;
        public byte[]           iData;
        public ColorModel       cModel = null;
        private ImageProducer   pro;
        private boolean         done = false;
        
        ImageBytes (Image img) {
                synchronized (this) {
                        pro = img.getSource();
                        pro.addConsumer(this);
                        pro.startProduction(this);
                        while (!done)
                                try { wait(); }
                                catch (InterruptedException e) { }
                }
        }

        public synchronized void imageComplete (int status) {
                pro.removeConsumer(this);
                done = true;
                notifyAll();
        }
        
        public void setColorModel (ColorModel model) {
                if (model instanceof IndexColorModel  &&  cModel == null)
                        cModel = model;
        }
        
        public void setDimensions (int width, int height) {
                this.width = width;
                this.height = height;
                iData = new byte [width * height];
        }
        
        public void setHints (int hintflags) {
        }
        
        public void setPixels (int x, int y, int w, int h, ColorModel model,
                               byte pixels[], int off, int scansize) {
                int doff = (y * width) + x;
                if (w == scansize  &&  w == width) {
                        System.arraycopy(pixels, off, iData, doff, h * w);
                }
                else {
                        for (int row = 0;  row < h;  row++) {
                                System.arraycopy(pixels, off, iData, doff, w);
                                doff += width;
                                off += scansize;
                        }
                }
        }
        
        public void setPixels (int x, int y, int w, int h, ColorModel model,
                               int pixels[], int off, int scansize) {
        }
        
        public void setProperties (Hashtable props) {
        }
}


The following is the implementation of the class:

public class TexView extends GridView {
        protected ImageBytes[]          iData = new ImageBytes[2];
        protected int                   ix = 0;
        protected Component             ap;
        protected float                 hWidth;
        protected IndexColorModel[][]   shades;
        private int                     sDark = 3;
        
        public TexView (Dimension window, int maxZ, Image wA, Image wB,
                        Component ap) {
                super(window, maxZ);
                iData[0] = new ImageBytes(wA);
                iData[1] = new ImageBytes(wB);
                this.ap = ap;
                hWidth = window.width / 2f;
                // Generate array of darkened color tables
                int steps = maxZ + sDark + 1;
                shades = new IndexColorModel[2][steps];
                for (int jj = 0; jj < 2; jj++) {
                        for (int ii = 0; ii < steps; ii++)
                                shades[jj][ii] = darker((IndexColorModel) 
iData[jj].cModel,
                                                        (float) (steps - ii) / steps);


                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        problem came out! (my guess)

                }
        }
        
        protected IndexColorModel darker (IndexColorModel pal, float inten) {
                int colors = pal.getMapSize();
                byte[] reds = new byte[colors];
                byte[] grns = new byte[colors];
                byte[] blus = new byte[colors];
                for (int ii = 0; ii < colors; ii++) {
                        int rgb = pal.getRGB(ii);
                        int red = (rgb >> 16) & 0xFF;
                        int grn = (rgb >> 8) & 0xFF;
                        int blu = rgb & 0xFF;
                        // Convert to HSB to darken and then back to RGB
                        float[] vals = Color.RGBtoHSB(red, grn, blu, null);
                        rgb = Color.HSBtoRGB(vals[0], vals[1], vals[2] * inten);
                        reds[ii] = (byte) (rgb >> 16);
                        grns[ii] = (byte) (rgb >> 8);
                        blus[ii] = (byte) rgb;
                }
                return new IndexColorModel(8, colors, reds, grns, blus);
        }

        protected Image makePic (byte[] buf, int width, int height, int z) {
                return ap.createImage(new MemoryImageSource(width, height,
                                                            shades[ix][z], buf, 0, 
width));
        }
        
        protected void getPoint (int idx, int z, int x, boolean b) {
                super.getPoint(idx, z, x, b);
                yy[idx] = Math.max(0, Math.min(window.height, yy[idx]));
                xx[idx] = Math.max(0, Math.min(window.width, xx[idx]));
        }
        
        protected float frontOff (float x, int z) {
                float height = ((eyeDist + vOff + z - 1) / eyeDist);
                return (((x + .5f) / window.width) - .5f) * height + .5f;
        }
        
        protected float sideOff (float xOff, int z) {
                float sRatio = eyeDist / (Math.abs(xOff - hWidth) / window.width);
                return (Math.abs(frontOff(xOff, z)) * sRatio) % 1f;
        }
        
        protected void colSlice (byte[] dst, int dstIdx, float texOff,
                                 int width, int height) {
                int sIdx = (int) (texOff * iData[ix].width);
                byte[] src = iData[ix].iData;
                int sWidth = iData[ix].width;
                int sHeight = iData[ix].height;
                int end = dstIdx + width * height;
                int sNum = 0;
                int sInc = sHeight * 2;
                int sDec = height * 2;
                for (int ii = dstIdx; ii < end; ii += width) {
                        dst[ii] = src[sIdx];
                        for (sNum += sInc; sNum > height; sNum -= sDec)
                                sIdx += sWidth;
                }
        }
        
        protected void textureSide (Graphics g, int x, int z) {
                int x2 = x < 1 ? x : x - 1;
                getPoint(0, z, x2, false);          // top front
                getPoint(1, z + 1, x2, false);      // top rear
                getPoint(2, z + 1, x2, true);       // bottom rear
                getPoint(3, z, x2, true);           // bottom front
                int wallX = Math.min(xx[0], xx[1]);
                int wallY = Math.min(yy[0], yy[1]);
                int width = Math.abs(xx[1] - xx[0]);
                int height = yy[3] - yy[0];
                byte[] dst = new byte[width * height];
                // Setup ratio counters
                int dec = width * 2;
                int topNum = 0;
                int topInc = (yy[1] - yy[0]) * 2;
                int botNum = 0;
                int botInc = (yy[3] - yy[2]) * 2;
                int top = yy[0] - wallY;
                int bot = height + top;
                int topStep = 1;
                int botStep = -topStep;
                for (int ii = 0; ii < width; ii++) {
                        int dx = x < 0 ? ii : width - ii - 1;
                        float tx = sideOff(x < 0 ? xx[0] + ii :
                                           window.width - xx[0] + ii, z);
                        colSlice(dst, dx + top * width, x < 0 ? tx : 1f - tx,
                                 width, bot - top);
                        for (topNum += topInc; topNum > width; topNum -= dec)
                                top += topStep;
                        for (botNum += botInc; botNum > width; botNum -= dec)
                                bot += botStep;
                }
                g.drawImage(makePic(dst, width, height, z + sDark), wallX,
                                    wallY, null);
        }

        protected void textureFront (Graphics g, int x, int z) {
                getPoint(0, z, x - 1, false);
                getPoint(1, z, x, true);
                int height = yy[1] - yy[0];
                int width = xx[1] - xx[0];
                byte[] dst = new byte[width * height];
                for (int ii = 0; ii < width; ii++) {
                        float tx = Math.abs(frontOff(xx[0] + ii, z)) % 1f;
                        colSlice(dst, ii, x < 0 ? 1f - tx : tx, width, height);
                }
                g.drawImage(makePic(dst, width, height, z), xx[0], yy[0], null);
        }
        
        protected void drawSq (Graphics g, MazeMap map, int x, int z) {
                if (map.isWall(x, z)) {
                        ix = map.isOdd(x, z) ? 0 : 1;
                        if (z > 0  &&  !map.isWall(x, z - 1))
                                textureFront(g, x, z);
                        if (x != 0  &&  !map.isWall(x < 0 ? x + 1 : x - 1, z))
                                textureSide(g, x, z);
                }
                else
                        drawFloorCeil(g, map, x, z);
        }
}

=====================================================================
To subscribe/unsubscribe, send mail to [EMAIL PROTECTED]
Java 2D Home Page: http://java.sun.com/products/java-media/2D/

Reply via email to