Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (576)
games submitted by our members
Games in WIP (498)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Procedural Texturing  (Read 1630 times)
0 Members and 1 Guest are viewing this topic.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Posted 2003-05-19 18:43:07 »

Hi,

I'm trying to generate a procedural texture based on a heightmap and a collection of images that have a low, optimal, and high value. Where the final image is a blending of these textures depending on the height of the heighmap. I'm having a bit of a brain fart though as how to best get the colors. Here is the class as it stands now, please note the commented section in createTexture() as this is where my main problem lies...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
package monkey.texture;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;

import monkey.locale.external.AbstractHeightMap;

public class ProceduralTexture {
    private ImageIcon proceduralTexture;
    private AbstractHeightMap heightMap;
    private ArrayList textureList;
    private int size;
   
    public ProceduralTexture(AbstractHeightMap heightMap) {
        textureList = new ArrayList();
        this.heightMap = heightMap;
        this.size = heightMap.getSize();
    }
   
    public void createTexture() {
        BufferedImage img = new BufferedImage(size,size,
                BufferedImage.TYPE_INT_RGB);
       
        float red = 0.0f;
        float green = 0.0f;
        float blue = 0.0f;
       
        for(int x = 0; x < size; x++) {
            for(int z = 0; z < size; z++) {
               
                for(int i = 0; i < textureList.size(); i++) {
                    //0 to 1 scalar, how much to use.
                   float scalar =
                        getTextureScale(heightMap.getTrueHeightAtPoint(x,z), i);
                    //red += texture(i)'s red value * scalar;
                   //green += texture(i)'s green value * scalar;
                   //blue += texture(i)'s blue value * scalar;
               }
               
                //set img's (x,z) pixel to (red,green,blue).
               
                //red = green = blue = 0
           }
        }
       
        //create ImageIcon proceduralTexture from img.
   }
   
    public void addTexture(ImageIcon image, int low, int optimal, int high) {
        BufferedImage img = new BufferedImage(image.getIconWidth(),
                image.getIconHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D)img.getGraphics();
        g.drawImage(image.getImage(), null, null);
        g.dispose();
       
        TextureTile tile = new TextureTile();
        tile.highHeight = high;
        tile.optimalHeight = optimal;
        tile.lowHeight = low;
        tile.imageData = img;
        textureList.add(tile);
    }
   
    public ImageIcon getImageIcon() {
        return proceduralTexture;
    }
   
    private float getTextureScale(int height, int tileIndex) {
        TextureTile tile = (TextureTile)textureList.get(tileIndex);
       
        if(height < tile.optimalHeight && height > tile.lowHeight) {
            return ((float)(height - tile.lowHeight)) /
                    (tile.optimalHeight - tile.lowHeight);
        } else if(height > tile.optimalHeight && height < tile.highHeight) {
            return ((float)(tile.highHeight - height)) /
                    (tile.highHeight - tile.optimalHeight);
        } else if(height == tile.optimalHeight) {
            return 1.0f;
        } else {
            return 0.0f;
        }
    }
   
    private class TextureTile {
        public BufferedImage imageData;
        public int lowHeight;
        public int optimalHeight;
        public int highHeight;
    }
   
   

}


I'm handling everything as BufferedImages right now, but if there is a better way to go about it, please by all means let me know.

Don't send a man to do a monkey's work.
Offline zingbat

Senior Member




Java games rock!


« Reply #1 - Posted 2003-05-19 23:44:46 »

Maybe it helps if you tell what is the visuals you want for your final blending and what shapes are you using for the particular images.

Just as a note, procedural textures don't work with pixel coordinates or pixels. They use logical coordinates and math formulas and because of that they are smaller and can draw any clip of the procedural in an image for any resolution required.

It's a tradeoff between space and computation power. Procedural textures don't need mipmaping and they are rendered with the best quality possible at any time but they are slow to compute on CPU. Pixel and vertex shaders are nothing more than procedural textures working on a GPU.
Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #2 - Posted 2003-05-20 01:14:21 »

Ok, let me clarify a little bit. I may have not picked the greatest of subject titles. I'm not having any trouble calculating the percentage per texture, etc. I'm having trouble getting the pixel from the input textures and setting the pixel for the output.

I basically need to get the red, green and blue values for each texture that applies, multiply that by a factor (0 to 1) and add them together. I then set this total as the pixel for the final texture. I just can't figure out how to get the individual color values.

Don't send a man to do a monkey's work.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kevglass

JGO Kernel


Medals: 85
Projects: 25


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #3 - Posted 2003-05-20 06:45:38 »

java.awt.PixelGrabber might work for you?

Or, if not, get the graphics of a BufferedImage, draw your source image onto the BufferedImage then use the getRGB() function on BufferedImage. Incidently, the value returned also contains the Alpha if its present.

I imagine your could also do this using the java.awt.image.ImageFilter stuff, but I suspect this would be more complicated. (but maybe more appropriate?)

Kev

Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #4 - Posted 2003-05-20 13:30:13 »

I've tried getRGB() from the BufferedImage. However, that returns a packed int for the RGB, and to tell you the truth, I wasn't sure how to retrieve the individual color values from this int. Nor do I know how to "repack" the modified colors into a new RGB value to put into the output image.

Don't send a man to do a monkey's work.
Offline kevglass

JGO Kernel


Medals: 85
Projects: 25


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #5 - Posted 2003-05-20 14:07:25 »

Assuming your BufferedImage is ARGB (or is it RGBA) ? Then the value you get back will be 8 bits per channel, so you can do something like (don't quote me)

int value = image.getRGB(x,y);

int alpha = (value & 0xFF000000) << 24;
int red = (value & 0x00FF0000) << 16;
int green = (value & 0x0000FF00) << 8;
int blue = (value & 0x000000FF);

I'm guessing this isn't dead on, but I suspect you'll get the idea Smiley

Kev

Offline bmyers

Junior Member





« Reply #6 - Posted 2003-05-20 16:31:40 »

I believe you can get the RGB values as an int[] if you get Raster from the BufferedImage via getRaster, then do a getPixels (?) from the Raster.

Offline EgonOlsen
« Reply #7 - Posted 2003-05-20 20:37:39 »

Quote
I believe you can get the RGB values as an int[] if you get Raster from the BufferedImage via getRaster, then do a getPixels (?) from the Raster.

Yes, you can do something like this
1  
2  
3  
Image output = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB); 
DataBufferInt data = (DataBufferInt) ((BufferedImage) output).getRaster().getDataBuffer();
int[] pixels = data.getData();


and then retrieve the color-values like this:

1  
2  
3  
int r= (pixels[pos] & 0x00ff0000) >> 16;
int g= (pixels[pos] & 0x0000ff00) >> 8;
int b= (pixels[pos] & 0x000000ff);


You may also write them back into the array after doing your modifications

1  
pixels[pos]=r<<16 | g<<8 | b


Note that i ignored the alpha channel in these examples. If needed, it has to be processed in a similar manner.

Offline Mojomonkey

Senior Member




ooh ooh eee eeee


« Reply #8 - Posted 2003-05-20 21:14:10 »

FANTASTIC!

Got it working, and it looks great!!!

Thanks everyone for your help.

Don't send a man to do a monkey's work.
Offline pepe

Junior Member




Nothing unreal exists


« Reply #9 - Posted 2003-05-21 06:52:49 »

Quote

Note that i ignored the alpha channel in these examples. If needed, it has to be processed in a similar manner.

Almost. due to the signed characteristics of the java numbers, the operations willl eventually give false results with alpha if the sign bit is set.  Be sure to use >>> instead of >>.
for more infos, see:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5121

Home page: http://frederic.barachant.com
------------------------------------------------------
GoSub: java2D gamechmark http://frederic.barachant.com/GoSub/GoSub.jnlp
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kevglass

JGO Kernel


Medals: 85
Projects: 25


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #10 - Posted 2003-05-21 07:04:48 »

Cooo, never knew about that one..

Thanks for jumping in there pepe!

Kev

Offline erikd

JGO Ninja


Medals: 15
Projects: 4
Exp: 14 years


Maximumisness


« Reply #11 - Posted 2003-05-21 08:58:53 »

Maybe not a really important point, but

1  
2  
3  
4  
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = pixel & 0xff;


will give you the correct results, even for alpha (because of the & 0xff mask which would otherwise not be necessary).

Offline pepe

Junior Member




Nothing unreal exists


« Reply #12 - Posted 2003-05-21 11:53:27 »

True.
Don't know if one of those is better, certainly none, but i had to point the >>> thing, because it might help on certain conditions.

Home page: http://frederic.barachant.com
------------------------------------------------------
GoSub: java2D gamechmark http://frederic.barachant.com/GoSub/GoSub.jnlp
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (18 views)
2014-04-16 09:08:23

BurntPizza (15 views)
2014-04-15 18:46:01

UprightPath (28 views)
2014-04-15 08:39:50

UprightPath (13 views)
2014-04-15 08:35:47

Porlus (29 views)
2014-04-15 06:48:38

tom_mai78101 (54 views)
2014-04-10 19:04:31

BurntPizza (111 views)
2014-04-09 14:06:04

tom_mai78101 (212 views)
2014-04-06 04:34:39

trollwarrior1 (181 views)
2014-04-05 03:06:45

CJLetsGame (187 views)
2014-04-01 17:16:10
List of Learning Resources
by Longarmx
2014-04-08 18:14:44

Good Examples
by matheus23
2014-04-06 04:51:37

Good Examples
by Grunnt
2014-04-04 06:48:46

Good Examples
by Grunnt
2014-04-04 06:48:37

Good Examples
by matheus23
2014-04-02 09:40:51

Good Examples
by matheus23
2014-04-02 09:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-12 06:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-12 06:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!