Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (756)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (842)
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  
  Q: Textures and Blending  (Read 3058 times)
0 Members and 1 Guest are viewing this topic.
Offline javazoid

Junior Devvie




Where's Flender?


« Posted 2005-05-12 13:23:28 »

A pair of misc OpenGL questions:

1) how to "fade out" a textured quad with a given alpha value ?


2) blending to a clear (0x000000) PBuffer leads to wrong results according to Porter&Duff principles:

I have two white circles. The upper (100% opaque) is painted before the lower (50% opaque).

OpenGL:


With OpenGL the circles look already blended to a black transparent background. Even more the lower circle alters the alpha of the upper circle. That's wrong.


Java2D:


With Java2D (AlphaComposite.SrcOver) the circles are painted in the right way.

Whats' wrong ?


Offline Orangy Tang

JGO Kernel


Medals: 57
Projects: 11


Monkey for a head


« Reply #1 - Posted 2005-05-12 14:06:54 »

Quote

1) how to "fade out" a textured quad with a given alpha value ?

Tinker with the alpha values over time. Easiest is to change the vertex colours (glColor4f if using immediate mode) and remember to use pure white if you don't want to tint your textures.

Quote
2) blending to a clear (0x000000) PBuffer leads to wrong results according to Porter&Duff principles:

Porter & Duff?

For the blending, whats the lower circle drawn as? Is it a pure white circle that you've changed the alpha value only, or have you changed the colour at all?

I suspect that you're getting different behaviour because Java2D is using a different blend mode. OpenGL defaults to a weighted blend - glBlendFunc(SRC_ALPHA, ONE_MINUS_SRC_ALPHA) - whereas Java2D looks like an additive blend - glBlendFunc(SRC_ALPHA, ONE). Try changing that before drawing.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Orangy Tang

JGO Kernel


Medals: 57
Projects: 11


Monkey for a head


« Reply #2 - Posted 2005-05-12 14:12:48 »

Quote

Porter & Duff?

Ah, I see. If I read correctly then the Java2D SrcOver sounds like it should be the same as OpenGL's default. I'd guess you're setting the vertex colours (or similar) to a darker colour without realising it.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline javazoid

Junior Devvie




Where's Flender?


« Reply #3 - Posted 2005-05-12 14:52:53 »

I tried to simplify the problem by using triangles instead of textured quads. The result is the same:

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  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
package JOGL;
 
 
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import net.java.games.jogl.*;
 
 
 
public class PBDemo extends JFrame implements GLEventListener {
  private static int        maxPbufferWidth = 720;
  private static int        maxPbufferHeight = 576;
  private GLDrawable        pbuffer;
  private BufferedImage     pbImage;
  private DataBufferInt     dbInt;
 
  private JLabel            label;
  private ImageIcon         image;
  private JScrollPane       scrollPane;
 
  public PBDemo() {
    setTitle( "Pbuffer Demo" );
    setSize( 640, 480 );
   
    // Create a temporary window to create a GLCanvas
    // that is never displayed on screen.
    Window tempWindow = new Window( this );
    tempWindow.setSize( 0, 0 );
    GLCanvas tempCanvas = GLDrawableFactory.getFactory().createGLCanvas( new GLCapabilities() );
    tempWindow.add( tempCanvas );
    tempWindow.setVisible( true );
   
    // Create a GLCapabilities object for the pbuffer
    GLCapabilities pbCaps = new GLCapabilities();
    pbCaps.setAlphaBits( 8 );
    pbCaps.setDoubleBuffered( false );
    pbuffer = tempCanvas.createOffscreenDrawable( pbCaps, maxPbufferWidth, maxPbufferHeight );
    // PBuffers are lazily created so the tempCanvas needs to run
    // through its display method once.
    tempCanvas.display();
     
    // Create the BufferedImage that will hold the pixel data
    // from the pbuffer.
    pbImage = new BufferedImage( maxPbufferWidth, maxPbufferHeight, BufferedImage.TYPE_INT_ARGB );
    // dbByte is the array that the pbuffer pixel data is stored in.
    dbInt = (DataBufferInt)pbImage.getRaster().getDataBuffer();
    pbuffer.addGLEventListener( this );
    pbuffer.display();
   
    // Display the pbuffer in a JScrollPane
    image = new ImageIcon( pbImage );
    label = new JLabel( image );
    scrollPane = new JScrollPane( label );
    getContentPane().add( scrollPane );
   
   
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        dispose();
        System.exit(0);
      }
    });
    setVisible( true );
  }
 
  public void displayChanged(GLDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
  }
 
  public void init( GLDrawable drawable ) {
    GL gl = drawable.getGL();    
    gl.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    gl.glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
    System.out.println("init");
    reshape( drawable, 0, 0, maxPbufferWidth, maxPbufferHeight );
  }
 
  public void display( GLDrawable drawable ) {
    GL gl = drawable.getGL();
    System.out.println("display");
    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();                                                      // Reset The View
    gl.glTranslatef(0.0f,0.0f,-5.0f);
   
    gl.glEnable(GL.GL_BLEND);
    gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA);
   
    gl.glColor4f(0f,0f,0f,1f);
    gl.glBegin( GL.GL_TRIANGLES );
      gl.glVertex3f( 0.0f, 0.0f, 0.0f );
      gl.glVertex3f( 1.0f, 0.0f, 0.0f );
      gl.glVertex3f( 0.0f, 1.0f, 0.0f );
    gl.glEnd();
   
    gl.glTranslatef(.5f,0.0f,0.0f);
   
    gl.glColor4f(0f,0f,0f,.5f);
    gl.glBegin( GL.GL_TRIANGLES );
      gl.glVertex3f( 0.0f, 0.0f, 0.0f );
      gl.glVertex3f( 1.0f, 0.0f, 0.0f );
      gl.glVertex3f( 0.0f, 1.0f, 0.0f );
    gl.glEnd();
   
    gl.glLoadIdentity();                                                      // Reset The View

       
    // Because opengl's origin is the lower left corner and java's origin
    // is the upper right corner that image will be flipped upside down.
    gl.glReadBuffer( GL.GL_FRONT );
    gl.glReadPixels( 0, 0, maxPbufferWidth, maxPbufferHeight, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, dbInt.getData() );
    gl.glFlush();
  }
 
  public void reshape( GLDrawable drawable, int x, int y, int width, int height ) {
    GL gl = drawable.getGL();
    GLU glu = drawable.getGLU();
   
    if (height <= 0) // avoid a divide by zero error!
        height = 1;
    final float h = (float)width / (float)height;
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL.GL_PROJECTION);
    gl.glLoadIdentity();
    glu.gluPerspective(45.0f, h, 1.0, 20.0);
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glLoadIdentity();
  }
 
  public static void main( String[] args ) {
    PBDemo demo = new PBDemo();
  }
}


The second triangle is 50% opaque and should not appear over the black 100% opaque triangle.


opengl:


java2d:



Offline Orangy Tang

JGO Kernel


Medals: 57
Projects: 11


Monkey for a head


« Reply #4 - Posted 2005-05-12 15:57:03 »

Thats... odd.

I tried that myself (with a quick conversion to just render direct into a LWJGL framebuffer) and it works as expected (ie the Java2d one). Nothing looks wrong from the code.

So I guess that leaves some oddity in either:
- pbuffers
- your drivers
- Jogl
My first guess would be some pbuffer irregularity, try it into a framebuffer and see if that helps.

Incidentally, why are you asking for help with Jogl code in the LWJGL forum? Huh

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #5 - Posted 2005-05-12 18:06:18 »

The output is correct. The blend function is incorrect for the result you're aiming for. Looking at the spec for AlphaComposite.SRC_OVER and the OpenGL red book, the blend function you want is glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
Offline javazoid

Junior Devvie




Where's Flender?


« Reply #6 - Posted 2005-05-13 05:08:50 »

This is GL_ONE, GL_ONE_MINUS_SRC_ALPHA.



Orangy, can you post your code ? And yes, I've used Jogl (shame on me Wink) just to compare my LWJGL results..

Maybe that's a driver issue. Don't know.. I'm with a NVidia Fx5700 (71.89, XP). Maybe someone can try the above src on ATI ?

Offline javazoid

Junior Devvie




Where's Flender?


« Reply #7 - Posted 2005-05-16 07:12:28 »

Here we are:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
            if (rule == AlphaComposite.SRC_OVER)
            {
                  // the best AlphaComposite.SRC_OVER combination
                  EXTBlendFuncSeparate.glBlendFuncSeparateEXT
                  (
                              GL11.GL_SRC_ALPHA,
                              GL11.GL_ONE_MINUS_SRC_ALPHA,
                              GL11.GL_ONE,
                              GL11.GL_ONE_MINUS_SRC_ALPHA
                  );
            }



Always remember to clear the Pbuffer with:

1  
2  
GL11.glClearColor(1f, 1f, 1f, 0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);


and you get:



which is 1:1 the same with the Java2D counterpart.

Cheers!

Offline javazoid

Junior Devvie




Where's Flender?


« Reply #8 - Posted 2005-05-16 08:41:20 »

... and finally I have the first stable implementation of SGL, my OpenGL accelerated java2d wrapper, robust enough to animate Castalia projects at least  200% faster, including pixels readback to bufferedimage. (goes up to 10-20 times better with other sample projects).

Java2D


LWJGL (SGL)


My special thanks fly to the LWJGL team!

Pages: [1]
  ignore  |  Print  
 
 

 
DesertCoockie (52 views)
2018-05-13 18:23:11

nelsongames (83 views)
2018-04-24 18:15:36

nelsongames (74 views)
2018-04-24 18:14:32

ivj94 (759 views)
2018-03-24 14:47:39

ivj94 (87 views)
2018-03-24 14:46:31

ivj94 (643 views)
2018-03-24 14:43:53

Solater (102 views)
2018-03-17 05:04:08

nelsongames (184 views)
2018-03-05 17:56:34

Gornova (426 views)
2018-03-02 22:15:33

buddyBro (1086 views)
2018-02-28 16:59:18
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
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!