Applying Colors to Objects - a possible solution

Started by tomzwo, March 10, 2005, 10:10:27 AM

Previous topic - Next topic

tomzwo

JPCT documentation states that objects may have textures (handled by the singleton TextureManager) - and that's it, full stop.

In a gaming environment this is all very well (since game artefacts and levels have to be designed via tools or similar) and in sophisticated object management scenarios, too - but in a simple situation you might want to be able to apply colors programmatically. At least, I wanted to...

The solution I found is based on TextureManager's ability to load from a stream (some code parts omitted):


// we have a color associated with an object (in this case within another class)
if(this.theColor != null)
{
// create identifying string (see below)
String tmp = new colorHelper(this.theColor).x11String();
// do we have the texture ?
         if(txman.containsTexture(tmp) == false)
         {
// create the texture - see below
           InputStream in;
           if((in = cr.createTexture(this.theColor)) != null)
           {
             txman.addTexture(tmp, new Texture(in));
             myObject.setTexture(tmp);
           }
         }
// ja: zuweisen
         else
           myObjcet.setTexture(tmp);
}


the identifying string is quite easy (normal X11-Style)

 public String x11String() {
   String rv = "#";
   String tmp;

   tmp = Integer.toHexString(this.red);
   rv += (tmp.length() >= 2 ? "" : "0") + tmp;
   tmp = Integer.toHexString(this.green);
   rv += (tmp.length() >= 2 ? "" : "0") + tmp;
   tmp = Integer.toHexString(this.blue);
   rv += (tmp.length() >= 2 ? "" : "0") + tmp;
   return(new String(rv));
 }



so far, nothing special - let's have a look at the creating method (this does not really match the call above, since my classes are a little more complicated) - createTexture is basically a call to createPngImageStream below with createImage and a fixed size of 8x8 which is perfectly sufficient


 public InputStream createPngImageStream(Image img)
 {
   if(img == null)
     return(null);
     
   PngEncoder enc = new PngEncoder(img);
   byte[] results = enc.pngEncode();
   return(new ByteArrayInputStream(results));
 }

 public Image createImage(int width, int height, Color color)
 {
   int[] pixels = new int[width * height];
   int n;
   
   for(n=0;n<width*height;n++)
     pixels[n] = color.getRGB();
     
   return(this.createImage(width, height, pixels));
 }

 private Image createImage(int width, int height, int[] pixels)
 {
   DirectColorModel cm = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
   MemoryImageSource prod = new MemoryImageSource(width, height, cm, pixels, 0, width);

// durch das Toolkit sind wir von Komponenten unabhaengig
   Toolkit tk = Toolkit.getDefaultToolkit();
   Image img = tk.createImage(prod);
   return(img);
 }



(the code above could be simplified for demonstration purposes, but - frankly - I do not feel like it)

I found the PngEncoder mentioned at http://www.chemaxon.com/marvin/doc/user/PngEncoder.java (the encoder there is GPL'ed); in its original version a few things have to be deleted from the source code (just calls to a progress displaying object). I'm using this encoder because my application needs to run in Java 1.1 environments - for Java 2 the builtin encoder methods might be a better idea.

Of course, this is somewhat crude - maybe a future version of TextureManager might be able to read from an Image...? (pretty please)

Also: this has not been tested outside my development environment so far (JDK 1.4.2 / Windows). I'll post updates as soon as I know more.

Comments welcome.

Of course, using a different algorithm for the pixel array, it is possible to create bit-patterned multicolor thingies (I do this, too)
-------------
Tom

tomzwo

and... while we're at it, there's a question I have, too: how can I display object edges in a different color (if it's possible at all) - meaning something like a mixture of wireframe and solid model in order to be able to view objects more clearly?
-------------
Tom

EgonOlsen

Adding a constructor that takes an Image should be easy and may appear in one of the next versions. Anyway, thanx for sharing the code. May i ask what kind of project that is?

tomzwo

basically its a simple object editor integrated into a (web) shop system: customers are able to configure products from a set of components and order them. 3D is the icing on the cake in order to give them an idea of the result. Depending on my customer, I'll post a link as soon as it's online and I'm allowed to...

have you thought about my question (edged in different color)?
-------------
Tom

EgonOlsen

Quote from: "tomzwo"have you thought about my question (edged in different color)?
Opps, i must have missed this one...to keep it short: That's hardly possible in jPCT without adding additional geometry that simulates it. You may draw a wireframe over the rendered scene, but that's most likely not what you want.