I modified Text2D to have it's geometry by Reference and tex maps don't
work. The file is called PointText2D.java. Thanks

On Wed, 9 Aug 2000, Chien Yang wrote:

> Will,
>       If you've followed what is stated in the doc, and it still doesn't
> work. Please, do send us a test program.
>
>
> By Reference: A new set of methods in Java 3D version 1.2 allows data to be
>               accessed by reference, directly from the user's arrays. To use
>               this feature, set the BY_REFERENCE bit in the vertexFormat field
>               of the constructor for this GeometryArray. In this mode, the
>               various set methods for coordinates, normals, colors, and
>               texture coordinates are not used. Instead, new methods are used
>               to set a reference to user-supplied coordinate, color, normal,
>               and texture coordinate arrays (e.g., setCoordRefFloat,
>               setColorRefFloat, etc.). Data in any array that is referenced by
>               a live or compiled GeometryArray object may only be modified via
>               the updateData method (subject to the ALLOW_REF_DATA_WRITE
>               capability bit). Applications must exercise care not to violate
>               this rule. If any referenced geometry data is modified outside of
>               the updateData method, the results are undefined.
>
>
> thanks,
>       Chien Yang
>       Java 3D Team.
>
>
> > MIME-Version: 1.0
> > Date: Wed, 9 Aug 2000 11:43:50 -0400
> > From: Will <[EMAIL PROTECTED]>
> > Subject: [JAVA3D] Referenced geometry with texture mapping help
> > Comments: To: [EMAIL PROTECTED]
> > To: [EMAIL PROTECTED]
> >
> > Hi, I'm trying to have a texture mapped quad using geometry by reference.
> > But it is never drawn. When I turn off the texture and just paint the quad
> > white, it shows up. And when I turn off geometry by reference, the texture
> > works. So i'm thinking it's some kind of bug. Please help! Any ideas?
> >
> > Will
> >
> > ===========================================================================
> > To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> > of the message "signoff JAVA3D-INTEREST".  For general help, send email to
> > [EMAIL PROTECTED] and include in the body of the message "help".
>
>

Will
// Will - I am extending a utility class class called Text2D so that
//  the geometry can be centered around something which isn't the origin

/*
 *      @(#)Text2D.java 1.9 00/02/10 13:16:14
 *
 * Copyright (c) 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */

//package com.sun.j3d.utils.geometry;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.awt.image.DataBufferInt;
import java.awt.*;
import java.util.Hashtable;
import javax.media.j3d.*;
import javax.vecmath.*;


/**
 * This class creates a texture-mapped rectangle which displays the
 * text string sent in by the user, given the appearance parameters
 * also supplied by the user.  The size of the rectangle (and its
 * texture map) is determined by the font parameters passed in to
 * the constructor.
 * The resulting Shape3D object is a transparent (except for the text)
 * rectangle located at (0, 0, 0) and extending up the positive y-axis and
 * out the positive x-axis.
 */
public class PointText2D extends Shape3D implements GeometryUpdater
{

    // This table caches FontMetrics objects to avoid the huge cost
    // of re-retrieving metrics for a font we've already seen.
    private static Hashtable metricsTable = new Hashtable();
    float rectangleScaleFactor = 1f/512f;

    private final float[] verts1 = {2f,2f,0,2f,-2f,0,-2f,-2f,0,-2f,2f,0};

    private static final float[] colorCoords = {
        1f, 1f, 1f,
        1f, 1f, 1f,
        1f, 1f, 1f,
        1f, 1f, 1f
    };
    private final float[] texCoords = {
        0f, -1f,
        0f, 0f,
        (-1f), 0f,
        (-1f), -1f
    };

    QuadArray rect;
    int widthTemp;
    int heightTemp;
    int realWidth;
    int realHeight;

    public RenderingAttributes ra;

    Color3f   color = new Color3f();
    String    fontName;
    int       fontSize, fontStyle;
    Point3f  origin = null;
    private static Canvas mFontRenderer = new Canvas();

    /**
     * Creates a Shape3D object which holds a
     * rectangle that is texture-mapped with an image that has
     * the specified text written with the specified font
     * parameters.
     *
     * @param text The string to be written into the texture map.
     * @param color The color of the text string.
     * @param fontName The name of the Java font to be used for
     *  the text string.
     * @param fontSize The size of the Java font to be used.
     * @param fontStyle The style of the Java font to be used.
     */
    public PointText2D(String text, Color3f color, String fontName,
                  int fontSize, int fontStyle, Point3f inOrigin) {

        color.set(color);
        fontName = fontName;
        fontSize = fontSize;
        fontStyle = fontStyle;
        origin = inOrigin;
        updateText2D(text, color, fontName, fontSize, fontStyle);
    }

    /*
     * Changes text of this Text2D to 'text'. All other
     * parameters (color, fontName, fontSize, fontStyle
     * remain the same.
     * @param text The string to be set.
     */
    public void setString(String text){
        updateText2D(text, color, fontName, fontSize, fontStyle);
    }

    private void updateText2D(String text, Color3f color, String fontName,
                  int fontSize, int fontStyle) {
        BufferedImage bImage = setupImage(text, color, fontName,
                                          fontSize, fontStyle);

        Texture2D t2d = setupTexture(bImage);

        rect = setupGeometry(bImage.getWidth(), bImage.getHeight());

        Appearance appearance = setupAppearance(t2d);

        setGeometry(rect);
        setAppearance(appearance);
    }


    /**
     * Sets the scale factor used in converting the image width/height
     * to width/height values in 3D.
     *
     * @param newScaleFactor The new scale factor.
     */
    public void setRectangleScaleFactor(float newScaleFactor) {
        rectangleScaleFactor = newScaleFactor;
    }

    /**
     * Gets the current scale factor being used in converting the image
     * width/height to width/height values in 3D.
     *
     * @return The current scale factor.
     */
    public float getRectangleScaleFactor() {
        return rectangleScaleFactor;
    }

    /**
     * Create the ImageComponent and Texture object.
     */
    private Texture2D setupTexture(BufferedImage bImage) {

        ImageComponent imageComponent =
            new ImageComponent2D(ImageComponent.FORMAT_RGBA,
                                 bImage);
        Texture2D t2d = new Texture2D(Texture2D.BASE_LEVEL,
                                      Texture.RGBA,
                                      bImage.getWidth(),
                                      bImage.getHeight());
        t2d.setMinFilter(t2d.BASE_LEVEL_LINEAR);
        t2d.setMagFilter(t2d.BASE_LEVEL_LINEAR);
        t2d.setImage(0, imageComponent);
        t2d.setEnable(true);

        return t2d;
    }

    /**
     * Creates a BufferedImage of the correct dimensions for the
     * given font attributes.  Draw the given text into the image in
     * the given color.  The background of the image is transparent
     * (alpha = 0).
     */
    private BufferedImage setupImage(String text, Color3f color,
                                     String fontName,
                                     int fontSize, int fontStyle) {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Font font = new java.awt.Font(fontName, fontStyle, fontSize);

        FontMetrics metrics;
        if ((metrics = (FontMetrics)metricsTable.get(font)) == null) {
            metrics = mFontRenderer.getFontMetrics(font);
            metricsTable.put(font, metrics);
        }
        int width = metrics.stringWidth(text);
        int descent = metrics.getMaxDescent();
        int ascent = metrics.getMaxAscent();
        int leading = metrics.getLeading();
        int height = descent + ascent;

        realWidth = width;
        realHeight= height;

        // Need to make width/height powers of 2 because of Java3d texture
        // size restrictions
        int pow = 1;
        for (int i = 1; i < 32; ++i) {
            pow *= 2;
            if (width <= pow)
                break;
        }
        width = Math.max (width, pow);
        pow = 1;
        for (int i = 1; i < 32; ++i) {
            pow *= 2;
            if (height <= pow)
                break;
        }
        height = Math.max (height, pow);

        // For now, jdk 1.2 only handles ARGB format, not the RGBA we want
        BufferedImage bImage = new BufferedImage(width, height,
                                                 BufferedImage.TYPE_INT_ARGB);
        Graphics offscreenGraphics = bImage.createGraphics();

        // First, erase the background to the text panel - set alpha to 0
        Color myFill = new Color(0f, 0f, 0f, 0f);
        offscreenGraphics.setColor(myFill);
        offscreenGraphics.fillRect(0, 0, width, height);

        // Next, set desired text properties (font, color) and draw String
        offscreenGraphics.setFont(font);
        Color myTextColor = new Color(color.x, color.y, color.z, 1f);
        offscreenGraphics.setColor(myTextColor);
        offscreenGraphics.drawString(text, 0, height - descent);

        return bImage;
    }

    /**
     * Creates a rectangle of the given width and height and sets up
     * texture coordinates to map the text image onto the whole surface
     * of the rectangle (the rectangle is the same size as the text image)
     */

    private QuadArray setupGeometry(int width, int height) {
        widthTemp = width;
        heightTemp= height;
        calcVerts();
        calcTex();

        QuadArray rect = new QuadArray(4, QuadArray.COORDINATES
                                        | QuadArray.TEXTURE_COORDINATE_2
//                                        | QuadArray.COLOR_3
                                        |QuadArray.BY_REFERENCE
                                        );
//      rect.setCoordinates(0,verts1);
//      rect.setTextureCoordinates(0, 0, texCoords);
//        rect.setColor(0, colorCoords);

        rect.setCoordRefFloat(verts1);
        rect.setTexCoordRefFloat(0, texCoords);
//        rect.setColorRefFloat(colorCoords);
        rect.setCapability(rect.ALLOW_REF_DATA_WRITE);

        return rect;
    }

    private void calcTex()
    {
        float rw = (float)realWidth/(float)widthTemp;
        float rh = (float)realHeight/(float)heightTemp;
        texCoords[0]=rw - 1f;
        texCoords[1]=-1f;
        texCoords[2]=rw - 1f;
        texCoords[3]=rh - 1f;
        texCoords[4]=-1f;
        texCoords[5]=rh - 1f;
        texCoords[6]=-1f;
        texCoords[7]=-1f;
    }

    private void calcVerts()
    {
        float zPosition = origin.z;
        float rectWidth = (float)realWidth * rectangleScaleFactor;
        float rectHeight = (float)realHeight * rectangleScaleFactor;

        verts1[0] = rectWidth + origin.x;
        verts1[1] = origin.y;
        verts1[2] = origin.z;

        verts1[3] = rectWidth + origin.x;
        verts1[4] = rectHeight + origin.y;
        verts1[5] = origin.z;

        verts1[6] = origin.x;
        verts1[7] = rectHeight + origin.y;
        verts1[8] = origin.z;

        verts1[9] = origin.x;
        verts1[10]= origin.y;
        verts1[11]= origin.z;
   }

    /**
     * Updates referenced vertex data held in QuadArray rect
     * -do NOT call this function manually
     */
    public void updateData(Geometry geometry)
    {
      calcVerts();
    }

    /**
     * Call this function to change rect vertex data
     */
    public void setScale(double inScale)
    {
      setRectangleScaleFactor((float)(inScale/512f));
      rect.updateData(this);
    }

    /**
     * Creates Appearance for this Shape3D.  This sets transparency
     * for the object (we want the text to be "floating" in space,
     * so only the text itself should be non-transparent.  Also, the
     * appearance disables lighting for the object; the text will
     * simply be colored, not lit.
     */
    private Appearance setupAppearance(Texture2D t2d)
    {
      Appearance appearance = new Appearance();
      ra = new RenderingAttributes();
      ra.setVisible(true);
      ra.setCapability(ra.ALLOW_VISIBLE_WRITE);
      TransparencyAttributes transp = new TransparencyAttributes();
      transp.setTransparency(0.5f);
      transp.setTransparencyMode(TransparencyAttributes.NICEST);
      appearance.setTransparencyAttributes(transp);
      appearance.setTexture(t2d);
      appearance.setRenderingAttributes(ra);

      appearance.setMaterial(null);
      return appearance;
    }
}

Reply via email to