aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util/TileRenderer2.java
blob: a774568890663af4ebd6ab09090c4adb590c9f43 (plain)
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
package com.jogamp.opengl.util;

import javax.media.opengl.GL2ES3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;

/**
 * See {@link TileRenderer}.
 * <p>
 * Enhanced for {@link GLAutoDrawable} usage.
 * </p>
 */
public class TileRenderer2 extends TileRenderer {
    private GLAutoDrawable glad;
    private GLEventListener[] listeners;
    private boolean[] listenersInit;    

    /**
     * Creates a new TileRenderer object
     */
    public TileRenderer2() {
        glad = null;
        listeners = null;
        listenersInit = null;
    }

    /**
     * 
     * <p>
     * Sets the size of the tiles to use in rendering. The actual
     * effective size of the tile depends on the border size, ie (
     * width - 2*border ) * ( height - 2 * border )
     * </p>
     * @param glad
     * @param border
     *           The width of the borders on each tile. This is needed
     *           to avoid artifacts when rendering lines or points with
     *           thickness > 1.
     * @throws IllegalStateException if an {@link GLAutoDrawable} is already attached
     */
    public void attachAutoDrawable(GLAutoDrawable glad, int border, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException {
        if( null != this.glad ) {
            throw new IllegalStateException("GLAutoDrawable already attached");
        }
        this.glad = glad;
        setTileSize(glad.getWidth(), glad.getHeight(), border);
        setPMVMatrixCallback(pmvMatrixCB);
        
        final int aSz = glad.getGLEventListenerCount();
        listeners = new GLEventListener[aSz];
        listenersInit = new boolean[aSz];
        for(int i=0; i<aSz; i++) {
            final GLEventListener l = glad.getGLEventListener(0);
            listenersInit[i] = glad.getGLEventListenerInitState(l);
            listeners[i] = glad.removeGLEventListener( l );
        }
        glad.addGLEventListener(tiledGLEL);
    }

    public void detachAutoDrawable() {
        if( null != glad ) {
            glad.removeGLEventListener(tiledGLEL);
            final int aSz = listenersInit.length;
            for(int i=0; i<aSz; i++) {
                final GLEventListener l = listeners[i];
                glad.addGLEventListener(l);
                glad.setGLEventListenerInitState(l, listenersInit[i]);
            }
            listeners = null;
            listenersInit = null;
            glad = null;
            pmvMatrixCB = null;
        }
    }

    /**
     * Rendering one tile, by simply calling {@link GLAutoDrawable#display()}.
     * 
     * @return true if there are more tiles to be rendered, false if the final image is complete
     * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachAutoDrawable(GLAutoDrawable, int) attached}
     *                               or imageSize is not set
     */
    public boolean display() throws IllegalStateException {
        if( null == glad ) {
            throw new IllegalStateException("No GLAutoDrawable attached");
        }
        glad.display();
        return !eot();
    }

    private final GLEventListener tiledGLEL = new GLEventListener() {
        @Override
        public void init(GLAutoDrawable drawable) {
            final int aSz = listenersInit.length;
            for(int i=0; i<aSz; i++) {
                final GLEventListener l = listeners[i];
                l.init(drawable);
                listenersInit[i] = true;
            }
        }
        @Override
        public void dispose(GLAutoDrawable drawable) {
            final int aSz = listenersInit.length;
            for(int i=0; i<aSz; i++) {
                listeners[i].dispose(drawable);
            }
        }
        @Override
        public void display(GLAutoDrawable drawable) {
            final GL2ES3 gl = drawable.getGL().getGL2ES3();
            
            beginTile(gl);
            
            final int aSz = listenersInit.length;
            for(int i=0; i<aSz; i++) {
                listeners[i].display(drawable);
            }
            
            endTile(gl);
        }
        @Override
        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
            final int aSz = listenersInit.length;
            for(int i=0; i<aSz; i++) {
                listeners[i].reshape(drawable, x, y, width, height);
            }
        }
    };
}