JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
GraphShape.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.graph.ui;
29
30import java.util.ArrayList;
31import java.util.List;
32
33import com.jogamp.graph.curve.OutlineShape;
34import com.jogamp.graph.curve.Region;
35import com.jogamp.graph.curve.opengl.GLRegion;
36import com.jogamp.graph.curve.opengl.RegionRenderer;
37import com.jogamp.graph.ui.layout.Padding;
38import com.jogamp.math.Vec3f;
39import com.jogamp.math.Vec4f;
40import com.jogamp.math.geom.AABBox;
41import com.jogamp.opengl.GL2ES2;
42import com.jogamp.opengl.GLProfile;
43import com.jogamp.opengl.util.texture.TextureSequence;
44
45/**
46 * Graph based {@link GLRegion} {@link Shape}
47 * <p>
48 * GraphUI is GPU based and resolution independent.
49 * </p>
50 * <p>
51 * GraphUI is intended to become an immediate- and retained-mode API.
52 * </p>
53 * @see Scene
54 */
55public abstract class GraphShape extends Shape {
56 protected final int renderModesReq;
57 protected int renderModes;
59 protected GLRegion region = null;
61 private final List<GLRegion> dirtyRegions = new ArrayList<GLRegion>();
62
63 /**
64 * Create a generic Graph based {@link GLRegion} UI {@link Shape}.
65 *
66 * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
67 */
68 protected GraphShape(final int renderModes) {
69 super();
70 this.renderModesReq = renderModes;
71 this.renderModes = renderModes;
72 }
73
74 /** Returns requested Graph {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}. */
75 public final int getRenderModesReq() { return renderModesReq; }
76
77 /**
78 * Returns validated Graph {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
79 * <p>
80 * May differ from {@link #getRenderModesReq()}, e.g. adding a {@link Region#COLORCHANNEL_RENDERING_BIT} for {@link #hasBorder()} etc.
81 * </p>
82 * <p>
83 * Potentially modified during {@link #validate(GL2ES2)} or {@link #validate(GLProfile)}.
84 * </p>
85 */
86 public final int getRenderModes() { return renderModes; }
87
88 /** Set the 2nd pass texture unit. */
89 public void setTextureUnit(final int pass2TexUnit) {
90 this.pass2TexUnit = pass2TexUnit;
91 if( null != region ) {
93 }
94 }
95
96 /**
97 * Sets the shape's Graph {@link OutlineShape}'s sharpness parameter. Default is {@link OutlineShape#DEFAULT_SHARPNESS}.
98 *
99 * Method issues {@link #markShapeDirty()}.
100 *
101 * @param sharpness Graph {@link OutlineShape}'s sharpness value, default is {@link OutlineShape#DEFAULT_SHARPNESS}.
102 * @return this shape for chaining.
103 */
104 public final GraphShape setSharpness(final float sharpness) {
105 this.oshapeSharpness = sharpness;
107 return this;
108 }
109 /**
110 * Return the shape's Graph {@link OutlineShape}'s sharpness value.
111 * @see #setSharpness(float)
112 */
113 public final float getSharpness() {
114 return oshapeSharpness;
115 }
116
117 @Override
118 public boolean hasColorChannel() {
120 }
121
122 private final void clearDirtyRegions(final GL2ES2 gl) {
123 for(final GLRegion r : dirtyRegions) {
124 r.destroy(gl);
125 }
126 dirtyRegions.clear();
127 }
128
129 @Override
130 protected final void clearImpl0(final GL2ES2 gl, final RegionRenderer renderer) {
131 clearImpl(gl, renderer);
132 clearDirtyRegions(gl);
133 if( null != region ) {
134 region.clear(gl);
135 }
136 }
137
138 @Override
139 protected final void destroyImpl0(final GL2ES2 gl, final RegionRenderer renderer) {
140 destroyImpl(gl, renderer);
141 clearDirtyRegions(gl);
142 if( null != region ) {
143 region.destroy(gl);
144 region = null;
145 }
146 }
147
148 @Override
149 protected void drawImpl0(final GL2ES2 gl, final RegionRenderer renderer, final Vec4f rgba) {
150 renderer.setColorStatic(rgba);
151 region.draw(gl, renderer);
152 }
153
154 public GLRegion getRegion() { return region; }
155
156 @Override
157 protected final void drawToSelectImpl0(final GL2ES2 gl, final RegionRenderer renderer) {
158 region.drawToSelect(gl, renderer);
159 }
160
161 /**
162 * Reset the {@link GLRegion} and reserving its buffers to have a free capacity for `vertexCount` and `indexCount` elements.
163 *
164 * In case {@link GLRegion} is `null`, a new instance is being created.
165 *
166 * In case the {@link GLRegion} already exists, it will be either {@link GLRegion#clear(GL2ES2) cleared} if the {@link GL2ES2} `gl`
167 * instance is not `null` or earmarked for deletion at a later time and a new instance is being created.
168 *
169 * Method shall be invoked by the {@link #addShapeToRegion(GLProfile, GL2ES2)} implementation
170 * before actually adding the {@link OutlineShape} to the {@link GLRegion}.
171 *
172 * {@link #addShapeToRegion(GLProfile, GL2ES2)} is capable to determine initial `vertexCount` and `indexCount` buffer sizes,
173 * as it composes the {@link OutlineShape}s to be added.
174 *
175 * {@link #resetGLRegion(GLProfile, GL2ES2, TextureSequence, OutlineShape)} maybe used for convenience.
176 *
177 * @param glp the used GLProfile, never `null`
178 * @param gl the optional current {@link GL2ES2} instance, maybe `null`.
179 * @param colorTexSeq optional {@link TextureSequence} for {@link Region#COLORTEXTURE_RENDERING_BIT} rendering mode.
180 * @param vertexCount the initial {@link GLRegion} vertex buffer size
181 * @param indexCount the initial {@link GLRegion} index buffer size
182 * @see #resetGLRegion(GLProfile, GL2ES2, TextureSequence, OutlineShape)
183 */
184 protected final void resetGLRegion(final GLProfile glp, final GL2ES2 gl, final TextureSequence colorTexSeq, int vertexCount, int indexCount) {
185 if( hasBorder() ) {
186 vertexCount += 8;
187 indexCount += 24;
188 }
189 if( null == region ) {
190 region = GLRegion.create(glp, renderModes, colorTexSeq, pass2TexUnit, vertexCount, indexCount);
191 } else if( null == gl ) {
192 dirtyRegions.add(region);
193 region = GLRegion.create(glp, renderModes, colorTexSeq, pass2TexUnit, vertexCount, indexCount);
194 } else {
195 region.clear(gl);
196 region.setBufferCapacity(vertexCount, indexCount);
197 }
198 }
199 /**
200 * Convenient {@link #resetGLRegion(GLProfile, GL2ES2, TextureSequence, int, int)} variant determining initial
201 * {@link GLRegion} buffer sizes via {@link Region#countOutlineShape(OutlineShape, int[])}.
202 *
203 * @param glp the used GLProfile, never `null`
204 * @param gl the optional current {@link GL2ES2} instance, maybe `null`.
205 * @param colorTexSeq optional {@link TextureSequence} for {@link Region#COLORTEXTURE_RENDERING_BIT} rendering mode.
206 * @param shape the {@link OutlineShape} used to determine {@link GLRegion}'s buffer sizes via {@link Region#countOutlineShape(OutlineShape, int[])}
207 * @see #resetGLRegion(GLProfile, GL2ES2, TextureSequence, int, int)
208 */
209 protected final void resetGLRegion(final GLProfile glp, final GL2ES2 gl, final TextureSequence colorTexSeq, final OutlineShape shape) {
210 final int[/*2*/] vertIndexCount = Region.countOutlineShape(shape, new int[2]);
211 resetGLRegion(glp, gl, colorTexSeq, vertIndexCount[0], vertIndexCount[1]);
212 }
213
214 @Override
215 protected final void validateImpl(final GL2ES2 gl, final GLProfile glp) {
216 if( null != gl ) {
217 clearDirtyRegions(gl);
218 }
219 if( isShapeDirty() ) {
222 }
223 // box has been reset
224 addShapeToRegion(glp, gl); // calls updateGLRegion(..)
225 if( hasBorder() ) {
226 // Also takes padding into account
229 } else if( hasPadding() ) {
230 final Padding p = getPadding();
231 final Vec3f l = box.getLow();
232 final Vec3f h = box.getHigh();
233 box.resize(l.x() - p.left, l.y() - p.bottom, l.z());
234 box.resize(h.x() + p.right, h.y() + p.top, l.z());
236 }
237 } else if( isStateDirty() ) {
239 }
240 }
241
242 static protected void addRectangle(final Region region, final float sharpness, final AABBox box, final Padding padding, final float borderThickness, final Vec4f color) {
243 final OutlineShape shape = new OutlineShape();
244 final Padding p = null != padding ? padding : Padding.None;
245 final float x1 = box.getMinX() - p.left;
246 final float x2 = box.getMaxX() + p.right;
247 final float y1 = box.getMinY() - p.bottom;
248 final float y2 = box.getMaxY() + p.top;
249 final float z = box.getMaxZ(); // on top
250 {
251 // Outer OutlineShape as Winding.CCW.
252 shape.moveTo(x1, y1, z);
253 shape.lineTo(x2, y1, z);
254 shape.lineTo(x2, y2, z);
255 shape.lineTo(x1, y2, z);
256 shape.lineTo(x1, y1, z);
257 shape.closeLastOutline(true);
258 shape.addEmptyOutline();
259 }
260 {
261 // Inner OutlineShape as Winding.CW.
262 final float dxy = borderThickness;
263 shape.moveTo(x1+dxy, y1+dxy, z);
264 shape.lineTo(x1+dxy, y2-dxy, z);
265 shape.lineTo(x2-dxy, y2-dxy, z);
266 shape.lineTo(x2-dxy, y1+dxy, z);
267 shape.lineTo(x1+dxy, y1+dxy, z);
268 shape.closeLastOutline(true);
269 }
270 shape.setIsQuadraticNurbs();
271 shape.setSharpness(sharpness);
272 region.addOutlineShape(shape, null, color);
273 box.resize(shape.getBounds()); // border <-> shape = padding, and part of shape size
274 }
275
276 protected void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) { }
277
278 protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) { }
279
280 protected abstract void addShapeToRegion(GLProfile glp, GL2ES2 gl);
281
282 @Override
283 public String getSubString() {
284 if( renderModesReq != renderModes ) {
285 return super.getSubString()+", renderMode[req "+Region.getRenderModeString(renderModesReq) + ", has "+Region.getRenderModeString(renderModes)+"]";
286 } else {
287 return super.getSubString()+", renderMode "+Region.getRenderModeString(renderModesReq);
288 }
289 }
290}
A Generic shape objects which is defined by a list of Outlines.
static final float DEFAULT_SHARPNESS
Initial getSharpness() value, which can be modified via setSharpness(float).
final void setIsQuadraticNurbs()
Claim this outline's vertices are all OutlineShape.VerticesState#QUADRATIC_NURBS, hence no cubic tran...
final void moveTo(final float x, final float y, final float z)
Start a new position for the next line segment at given point x/y (P1).
final void lineTo(final float x, final float y, final float z)
Add a line segment, intersecting the last point and the given point x/y (P1).
final void setSharpness(final float s)
Sets sharpness, defaults to DEFAULT_SHARPNESS.
final void closeLastOutline(final boolean closeTail)
Closes the last outline in the shape.
final void addEmptyOutline()
Add a new empty Outline to the end of this shape's outline list.
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
final void addOutlineShape(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor)
Add the given OutlineShape to this region with the given optional AffineTransform.
Definition: Region.java:616
static final int COLORCHANNEL_RENDERING_BIT
Rendering-Mode bit for Region to optionally enable a color-channel per vertex.
Definition: Region.java:148
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
static final int DEFAULT_TWO_PASS_TEXTURE_UNIT
Definition: Region.java:181
final void markStateDirty()
Mark this region's render-state dirty, i.e.
Definition: Region.java:811
static final int[] countOutlineShape(final OutlineShape shape, final int[] vertIndexCount)
Count required number of vertices and indices adding to given int[2] vertIndexCount array.
Definition: Region.java:572
static boolean hasColorChannel(final int renderModes)
Returns true if render mode has a color channel, i.e.
Definition: Region.java:231
static boolean hasColorTexture(final int renderModes)
Returns true if render mode has a color texture, i.e.
Definition: Region.java:240
A GLRegion is the OGL binding of one or more OutlineShapes Defined by its vertices and generated tria...
Definition: GLRegion.java:70
final void drawToSelect(final GL2ES2 gl, final RegionRenderer renderer)
Perform glSelect false color rendering: pass1 w/o any color texture nor channel, use static select co...
Definition: GLRegion.java:553
final GLRegion clear(final GL2ES2 gl)
Clears all buffers, i.e.
Definition: GLRegion.java:436
final void destroy(final GL2ES2 gl)
Delete and clear the associated OGL objects.
Definition: GLRegion.java:460
final void draw(final GL2ES2 gl, final RegionRenderer renderer)
Renders the associated OGL objects specifying current width/hight of window for optional multi pass r...
Definition: GLRegion.java:518
abstract void setTextureUnit(final int pass2TexUnit)
Set the 2nd pass texture unit.
final boolean setBufferCapacity(final int verticesCount, final int indicesCount)
Set the renderer buffers pre-emptively for given vertices- and index counts.
Definition: GLRegion.java:301
static GLRegion create(final GLProfile glp, int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit, final int initialVerticesCount, final int initialIndicesCount)
Create a GLRegion using the passed render mode.
Definition: GLRegion.java:109
final void setColorStatic(final Vec4f rgbaColor)
Graph based GLRegion Shape.
Definition: GraphShape.java:55
final int getRenderModes()
Returns validated Graph Region render modes, see create(..).
Definition: GraphShape.java:86
final float getSharpness()
Return the shape's Graph OutlineShape's sharpness value.
void clearImpl(final GL2ES2 gl, final RegionRenderer renderer)
void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer)
void setTextureUnit(final int pass2TexUnit)
Set the 2nd pass texture unit.
Definition: GraphShape.java:89
final void resetGLRegion(final GLProfile glp, final GL2ES2 gl, final TextureSequence colorTexSeq, final OutlineShape shape)
Convenient resetGLRegion(GLProfile, GL2ES2, TextureSequence, int, int) variant determining initial GL...
final void clearImpl0(final GL2ES2 gl, final RegionRenderer renderer)
Custom clear(GL2ES2, RegionRenderer) task, called 1st.
final void drawToSelectImpl0(final GL2ES2 gl, final RegionRenderer renderer)
Actual draw implementation, called by drawToSelect(GL2ES2, RegionRenderer).
void drawImpl0(final GL2ES2 gl, final RegionRenderer renderer, final Vec4f rgba)
Actual draw implementation, called by draw(GL2ES2, RegionRenderer).
boolean hasColorChannel()
Returns true if implementation uses an extra color channel or texture which will be modulated with th...
final void destroyImpl0(final GL2ES2 gl, final RegionRenderer renderer)
Custom destroy(GL2ES2, RegionRenderer) task, called 1st.
final GraphShape setSharpness(final float sharpness)
Sets the shape's Graph OutlineShape's sharpness parameter.
final int getRenderModesReq()
Returns requested Graph Region render modes, see create(..).
Definition: GraphShape.java:75
final void resetGLRegion(final GLProfile glp, final GL2ES2 gl, final TextureSequence colorTexSeq, int vertexCount, int indexCount)
Reset the GLRegion and reserving its buffers to have a free capacity for vertexCount and indexCount e...
final void validateImpl(final GL2ES2 gl, final GLProfile glp)
abstract void addShapeToRegion(GLProfile glp, GL2ES2 gl)
static void addRectangle(final Region region, final float sharpness, final AABBox box, final Padding padding, final float borderThickness, final Vec4f color)
GraphShape(final int renderModes)
Create a generic Graph based GLRegion UI Shape.
Definition: GraphShape.java:68
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Definition: Shape.java:87
Padding getPadding()
Returns unscaled Padding of this shape, which is included in unscaled getBounds() and also includes t...
Definition: Shape.java:387
final boolean isStateDirty()
Returns the rendering dirty state, see markStateDirty().
Definition: Shape.java:705
boolean hasPadding()
Returns true if setPaddding(Padding) added a non Padding#zeroSize() spacing to this shape.
Definition: Shape.java:390
final boolean hasBorder()
Returns true if a border has been enabled via setBorder(float, Padding).
Definition: Shape.java:408
final float getBorderThickness()
Returns the border thickness, see setBorder(float, Padding).
Definition: Shape.java:411
boolean isShapeDirty()
Returns the shape's dirty state, see markShapeDirty().
Definition: Shape.java:701
final Vec4f getBorderColor()
Definition: Shape.java:1476
final void markShapeDirty()
Marks the shape dirty, causing next draw() to recreate the Graph shape and reset the region.
Definition: Shape.java:688
final Vec4f rgbaColor
Default base-color w/o color channel, will be modulated w/ pressed- and toggle color.
Definition: Shape.java:261
final Shape setRotationPivot(final float px, final float py, final float pz)
Set unscaled rotation origin, aka pivot.
Definition: Shape.java:620
GraphUI CSS property Padding, unscaled space belonging to the element and included in the element's s...
Definition: Padding.java:38
final float top
Top value (unscaled)
Definition: Padding.java:43
final float left
Left value (unscaled)
Definition: Padding.java:49
static final Padding None
Zero padding constant.
Definition: Padding.java:40
final float right
Right value (unscaled)
Definition: Padding.java:45
final float bottom
Bottom value (unscaled)
Definition: Padding.java:47
3D Vector based upon three float components.
Definition: Vec3f.java:37
4D Vector based upon four float components.
Definition: Vec4f.java:37
boolean isEqual(final Vec4f o, final float epsilon)
Equals check using a given FloatUtil#EPSILON value and FloatUtil#isEqual(float, float,...
Definition: Vec4f.java:374
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final Vec3f getHigh()
Returns the maximum right-top-near (xyz) coordinate.
Definition: AABBox.java:131
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
Definition: AABBox.java:140
final AABBox resize(final AABBox newBox)
Resize the AABBox to encapsulate another AABox.
Definition: AABBox.java:274
final Vec3f getCenter()
Returns computed center of this AABBox of getLow() and getHigh().
Definition: AABBox.java:737
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
Protocol for texture sequences, like animations, movies, etc.