Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (512)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
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  
  "Glossy" effect?  (Read 3527 times)
0 Members and 1 Guest are viewing this topic.
Offline onlytoine

Senior Newbie





« Posted 2011-03-16 20:02:18 »

Hello,

Do you know a way to create a "glossy" effect in java?

Toine
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2011-03-16 20:10:07 »

Glossy effect? Example?

Offline philfrei
« Reply #2 - Posted 2011-03-16 20:25:26 »

Depends upon what you mean. There are 3D lighting effects that might apply.

If you mean 2D, like a halo, one can overlay a semitransparent graphic.

If you mean like a shiny gel button, I did this by looking at photoshop "how to" articles, and translating the steps to Java. For example, to edit a graphic in Java, you would want to look into BufferedImage which allows you to do pixel-by-pixel editing, including the Alpha (transparency) values.

"It's after the end of the world! Don't you know that yet?"
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2011-03-17 01:42:37 »

If you want a gradiency then there is GradientPaint:
http://download.oracle.com/javase/tutorial/2d/geometry/strokeandfill.html

Offline onlytoine

Senior Newbie





« Reply #4 - Posted 2011-03-17 10:04:05 »

Hello,

Thanks for reply, you can find example by typing "glossy effect" in Google Image.

@philfrei : have you a shreable code sample to illustrate what you did?

Regards,
Toine
Offline philfrei
« Reply #5 - Posted 2011-03-17 21:50:09 »

Quote
@philfrei : have you a shreable code sample to illustrate what you did?
The glossy effect I did for Hexara is OK, not great. You can see it at www.hexara.com, either by looking at the game (in progress) itself or at the blog entry for July 2010. At that entry there is a clickable button on the right, copper colored, that clicks through some flat and somewhat glossy forms.

Below is a code sample for a circular gel. I don't know how useful it is, because it assumes the existence of an oval gradient tool that I wrote. I tried to put in comments to explain what the data created by that tool looks like. There are probably lots of ways to make the code clearer or more efficient! And better settings for the gradients as well. Also, I cut and paste it out of the working program, so I hope I didn't create any errors in the process. But at least you can see the basic idea in action. (And I can get feedback if there are better ways to do this!)

Here's the basic concept. Let's say you have an image that is just a flat color. To give it depth, there are three "classic" components that are added:

1) Darkening around the edges. For example, take the R, the G, the B and subtract an amount that is calculated based upon the distance from the edge.

2) Top light. For example, based upon the distance from the top edge, add a small amount to the R, G, & B components. A fancier system would have a way to do lighting from any angle, on the fly, but I haven't advanced that far.

3) Inner glow. This is usually accomplished by an oval that is placed in the lower center. The R, G, & B values are advanced as a function of how close they are to the center of this inner-glow region.

With a BufferedImage, you can create a "raster" and iterate through each pixel, putting in the base color + the modifications that arise from the three gradients.

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  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
   private int width;
   private int height;
   private BufferedImage baseImg;
   private int[] pixel = new int[4];
   
   public int getXMid(){return width/2;}
   public int getYMid(){return height/2;}
   
   // C O N S T R U C T O R //
   public RoundGel(int radius, Color color, String iconName){
     
      this.width = radius*2;
      this.height = width;
         
      int red = color.getRed();
      int green = color.getGreen();
      int blue = color.getBlue();
      int alpha = color.getAlpha();
     
      /*
      * The "alphaChannel" array will hold info used to create
      * the base shape.
      * Outside the radius, integer = 0 (wholly transparent),
      * inside the radius, integer = alpha (a value we passed
      * in the constructor as part of "color").
      * On the radius edge, I calculate an "antialiasing" int.  
      */

      OvalBandMaskGradient aCh = new OvalBandMaskGradient(
            width, height,
            radius, 0, alpha,alpha,0,alpha);
      ArrayList<Integer> alphaChannel = aCh.getVector();
     
      /*
      * The "darkenEdge" will hold data to be used in modifying
      * the base color of the image. In this example, the amount of
      * darkening will be a gradient that goes from 64 to 0 in the space
      * of 6 pixels from the edge.
      */

      OvalBandMaskGradient deMask = new OvalBandMaskGradient(width, height,
            radius, (radius - 6), 64,0,64,0);
      ArrayList<Integer> darkenEdge = deMask.getVector();
     
      /*
      * The "innerGlow" array will hold data used to lighten the graphic
      * around the lower middle. In this example I go from 0 at the outer
      * edge to a boost of 72 at the center, as a gradient.
      */

      int igWidth = width - width/3;
      int igHeight = height/3;
      OvalBandMaskGradient igMask = new OvalBandMaskGradient(
            igWidth, igHeight,
            igHeight/2, 0,
            0,64,0,64);
      ArrayList<Integer> innerGlow = igMask.getVector();
      /*
      * The "innerGlow" array fits "within" the main graphic, so
      * we get some numbers to help invoke it at the right
      * position as we iterate through the main graphic.
      */

      int igXStart = (width - igWidth)/2;
      int igYStart = ((height - igHeight) - (height-igHeight)/6);
      int igIdx;
     
      // We will assemble the gel in this variable.
      baseImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
      WritableRaster baseRaster = baseImg.getRaster();
      int idx;

      int whitelight; // used to calculate a gradient on the fly
      for (int jj=0; jj<height; ++jj) {
         for (int ii=0; ii<width; ++ii){
           
            idx = ii + jj*width;
           
            // core color and shape + edge darkening values
            pixel[0] = Math.max(0, red - darkenEdge.get(idx));
            pixel[1] = Math.max(0, green - darkenEdge.get(idx));
            pixel[2] = Math.max(0, blue - darkenEdge.get(idx));
            pixel[3] = alphaChannel.get(idx);
                     
            // for top light, whitening caculated on the fly as
            // a function of the distance from the top, and
            // only applied above the midpoint
            if (jj < radius){
               whitelight = (radius-jj)*3;
               pixel[0] = Math.min(255, pixel[0] + whitelight);
               pixel[1] = Math.min(255, pixel[1] + whitelight);
               pixel[2] = Math.min(255, pixel[2] + whitelight);
            }

            // add inner glow component, if we are within the
            // inner glow area
            if (ii>=igXStart && ii<(igXStart+igWidth)
                  && jj>=igYStart && jj<(igYStart+igHeight)){
               
               // get corresponding "innerGlow" index
               igIdx = (ii-igXStart) + ((jj-igYStart)*igWidth);

               pixel[0] = Math.min(255, pixel[0] + innerGlow.get(igIdx));
               pixel[1] = Math.min(255, pixel[1] + innerGlow.get(igIdx));
               pixel[2] = Math.min(255, pixel[2] + innerGlow.get(igIdx));
            }
                       
            baseRaster.setPixel(ii, jj, pixel);
         }
      }
   }
   

"It's after the end of the world! Don't you know that yet?"
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #6 - Posted 2011-03-18 01:15:56 »

There is also quite simply, like I stated before, GradientPaint which is very flexible in the number of ways you can add a glossy effect.

Offline philfrei
« Reply #7 - Posted 2011-03-18 06:13:41 »

Some of what I did in the code example is covered in the "FAQ" for 2D in this site. [Edit: Looks like there are a lot of resources on the "Pixel Art" thread as well, even if they are several years old.]

When I was first asking around for how to do glossy gels (at other sites, before discovering JavaGaming) the most common answer I got was to just do it in Photoshop or some other art program, and import the graphic! That probably IS the easiest, most efficient way to go. It seems like it is a common enough need, though, that there would be some tool in Java that can spit them out easily. [Edit: I bet there IS, in the Pixel Art thread.]

But I didn't want to buy PhotoShop or learn an art program and wanted to know how to do it myself, in Java, and understand better how it worked. Hence coding it pixel by pixel. At first, I tried to make it work with the GradientPaint and RadialGradientPaint, but because there were various odd-shaped parts that contribute to the effect (e.g., the "inner glow" according to Photoshop tutorials is usually an oval gradient, not circular) that I ended up creating a tool that generated gradients as an oval, and now routinely use it because it has anti-aliasing built in. But if there is an easier way to make a glossy gel button in Java, using the prebuilt gradient paints, I'd appreciate being shown how that would work.

"It's after the end of the world! Don't you know that yet?"
Offline onlytoine

Senior Newbie





« Reply #8 - Posted 2011-03-18 09:50:33 »

Thanks for replies  Cheesy

Hexara seems to be a good game project, congratulations! Wink

About glossy effect, I wish something like:
http://www.istockphoto.com/stock-illustration-9594205-music-and-media-icons-with-glossy-effect.php

It's a bit like a piece of "plastic" and I would like to create this effect on any images.

Toine
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #9 - Posted 2011-03-18 17:55:54 »

@philfrei
You can draw any shape using the present GradientPaint or RadialGradientPaint.
1  
2  
g2d.setPaint(gradientPaint);
g2d.fill(new Ellipse2D.Double(x,y,width,height));

Is this what you were asking about?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline philfrei
« Reply #10 - Posted 2011-03-19 05:31:50 »

@philfrei
You can draw any shape using the present GradientPaint or RadialGradientPaint.
1  
2  
g2d.setPaint(gradientPaint);
g2d.fill(new Ellipse2D.Double(x,y,width,height));

Is this what you were asking about?
Not exactly. It works for some things, but even with circular gradient paint with the high point in the center, if it is painted within an oval, the edges will all have different values, based on how far they are from the center. Does that make sense? It seems hard to explain.
Example: oval 60 wide, 30 tall. Circular gradient: go from 0 to 100 and back. If the gradient is set so that the left and right edges are 0 and the center 100, the gradient will only go down to 50 at the top and bottom edge. If the gradient is set so at the top and bottome it reaches 0, the gradient will also reach 0 at 15 and 45 on the vertical, giving one a circle within the oval. In other words, the oval shape is basically a "mask" over the gradient.
These plastic gels have tricky gradient shapes internally, where the gradient is steeper or shallower depending upon the direction.

"It's after the end of the world! Don't you know that yet?"
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #11 - Posted 2011-03-19 06:42:49 »

Oh so you need RadialGradientPaint?
http://ra4king.is-a-geek.net/javadocs/java/awt/RadialGradientPaint.html

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.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (39 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (66 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!