summaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/util/J2DOverlay.java
blob: 3bb4de9ee92ab5c6f6b9b10857927394aeabb1e9 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * - Redistribution of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * 
 * You acknowledge that this software is not designed or intended for use
 * in the design, construction, operation or maintenance of any nuclear
 * facility.
 * 
 * Sun gratefully acknowledges that this software was originally authored
 * and developed by Kenneth Bradley Russell and Christopher John Kline.
 */

package com.sun.opengl.util;

import java.awt.Graphics2D;

import javax.media.opengl.*;
import com.sun.opengl.util.texture.*;

/** Provides a Java 2D overlay on top of an arbitrary GLDrawable,
    making it easier to do things like draw text and images on top of
    an OpenGL scene while still maintaining reasonably good
    efficiency. For correct operation, the drawable should be
    allocated with alpha bits enabled, as the J2DOverlay uses alpha
    blending to make portions of itself transparent. */

public class J2DOverlay {
  private GLDrawable drawable;
  private J2DTextureRenderer renderer;
  private boolean contentsLost;

  /** Creates a new Java 2D overlay on top of the specified
      GLDrawable. */
  public J2DOverlay(GLDrawable drawable) {
    this.drawable = drawable;
  }

  /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for
      rendering into the overlay. The returned object should be
      disposed of using the normal {@link java.awt.Graphics#dispose()
      Graphics.dispose()} method once it is no longer being used.

      @return a new {@link java.awt.Graphics2D Graphics2D} object for
        rendering into the backing store of this renderer
  */
  public Graphics2D createGraphics() {
    // Validate the size of the renderer against the current size of
    // the drawable
    validateRenderer();
    return renderer.createGraphics();
  }

  /** Indicates whether the Java 2D contents of the overlay were lost
      since the last time {@link #createGraphics} was called. This
      method should be called immediately after calling {@link
      #createGraphics} to see whether the entire contents of the
      overlay need to be redrawn or just the region the application is
      interested in updating.

      @return whether the contents of the overlay were lost since the
        last render
  */
  public boolean contentsLost() {
    return contentsLost;
  }

  /** Synchronizes the contents of the Java 2D rendering down to the
      OpenGL texture.

      @param x the x coordinate (in Java 2D coordinates -- relative to
        upper left) of the region to update
      @param y the y coordinate (in Java 2D coordinates -- relative to
        upper left) of the region to update
      @param width the width of the region to update
      @param height the height of the region to update

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void sync(int x, int y, int width, int height) throws GLException {
    renderer.sync(x, y, width, height);
  }

  /** Draws the entire contents of the overlay on top of the OpenGL
      drawable. This is a convenience method which encapsulates all
      portions of the rendering process; if this method is used,
      {@link #beginRendering}, {@link #endRendering}, etc. should not
      be used. This method should be called while the OpenGL context
      for the drawable is current, and after your OpenGL scene has
      been rendered.

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void drawAll() throws GLException {
    beginRendering();
    draw(0, 0, drawable.getWidth(), drawable.getHeight());
    endRendering();
  }

  /** Begins the OpenGL rendering process for the overlay. This is
      separated out so advanced applications can render independent
      pieces of the overlay to different portions of the drawable.

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void beginRendering() throws GLException {
    renderer.beginOrthoRendering(drawable.getWidth(), drawable.getHeight());
  }

  /** Ends the OpenGL rendering process for the overlay. This is
      separated out so advanced applications can render independent
      pieces of the overlay to different portions of the drawable.

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void endRendering() throws GLException {
    renderer.endOrthoRendering();
  }

  /** Draws the specified sub-rectangle of the overlay on top of the
      OpenGL drawable. {@link #beginRendering} and {@link
      #endRendering} must be used in conjunction with this method to
      achieve proper rendering results. This method should be called
      while the OpenGL context for the drawable is current, and after
      your OpenGL scene has been rendered.

      @param x the lower-left x coordinate (relative to the lower left
        of the overlay) of the rectangle to draw
      @param y the lower-left y coordinate (relative to the lower left
        of the overlay) of the rectangle to draw
      @param width the width of the rectangle to draw
      @param height the height of the rectangle to draw

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void draw(int x, int y, int width, int height) throws GLException {
    draw(x, y, x, y, width, height);
  }

  /** Draws the specified sub-rectangle of the overlay at the
      specified x and y coordinate on top of the OpenGL drawable.
      {@link #beginRendering} and {@link #endRendering} must be used
      in conjunction with this method to achieve proper rendering
      results. This method should be called while the OpenGL context
      for the drawable is current, and after your OpenGL scene has
      been rendered.

      @param screenx the on-screen x coordinate at which to draw the rectangle
      @param screeny the on-screen y coordinate (relative to lower left) at
        which to draw the rectangle
      @param overlayx the x coordinate of the pixel in the overlay of
        the lower left portion of the rectangle to draw
      @param overlayy the y coordinate of the pixel in the overlay
        (relative to lower left) of the lower left portion of the
        rectangle to draw
      @param width the width of the rectangle to draw
      @param height the height of the rectangle to draw

      @throws GLException If an OpenGL context is not current when this method is called
  */
  public void draw(int screenx, int screeny,
                   int overlayx, int overlayy,
                   int width, int height) throws GLException {
    renderer.drawOrthoRect(screenx, screeny,
                           overlayx, overlayy,
                           width, height);
  }

  //----------------------------------------------------------------------
  // Internals only below this point
  //

  private void validateRenderer() {
    if (renderer == null) {
      renderer = new J2DTextureRenderer(drawable.getWidth(),
                                        drawable.getHeight(),
                                        true);
      contentsLost = true;
    } else if (renderer.getWidth() != drawable.getWidth() ||
               renderer.getHeight() != drawable.getHeight()) {
      renderer.setSize(drawable.getWidth(), drawable.getHeight());
      contentsLost = true;
    } else {
      contentsLost = false;
    }
  }
}