diff --git a/.idea/libraries/Maven__org_apache_commons_commons_math4_core_4_0_SNAPSHOT.xml b/.idea/libraries/Maven__org_apache_commons_commons_math4_core_4_0_SNAPSHOT.xml index 8a3fe527..99855144 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_math4_core_4_0_SNAPSHOT.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_math4_core_4_0_SNAPSHOT.xml @@ -1,13 +1,13 @@ - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_4_0_SNAPSHOT.xml b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_4_0_SNAPSHOT.xml index 85b95758..4d9cd944 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_4_0_SNAPSHOT.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_4_0_SNAPSHOT.xml @@ -1,13 +1,13 @@ - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_core_4_0_SNAPSHOT.xml b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_core_4_0_SNAPSHOT.xml index 6bd6f5d4..1d619a58 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_core_4_0_SNAPSHOT.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_core_4_0_SNAPSHOT.xml @@ -1,13 +1,13 @@ - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_exception_4_0_SNAPSHOT.xml b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_exception_4_0_SNAPSHOT.xml index b5980b99..492065a1 100644 --- a/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_exception_4_0_SNAPSHOT.xml +++ b/.idea/libraries/Maven__org_apache_commons_commons_math4_legacy_exception_4_0_SNAPSHOT.xml @@ -1,13 +1,13 @@ - + - + - + \ No newline at end of file diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/GLChartPanel.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/GLChartPanel.java index ecc670d0..292a1e40 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/GLChartPanel.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/GLChartPanel.java @@ -1647,7 +1647,12 @@ public class GLChartPanel extends GLJPanel implements IChartPanel{ * @return View image */ public BufferedImage paintViewImage(int width, int height) { - BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + BufferedImage image; + if (this.chart.containsGLPlot()) { + image = JOGLUtil.paintViewImage(this.chart, width, height); + } else { + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + } Graphics2D g = image.createGraphics(); paintGraphics(g); @@ -1682,8 +1687,12 @@ public class GLChartPanel extends GLJPanel implements IChartPanel{ */ public BufferedImage paintViewImage(int width, int height, int dpi) { double scaleFactor = dpi / 72.0; - BufferedImage image = new BufferedImage((int)(width * scaleFactor), (int)(height * scaleFactor), - BufferedImage.TYPE_INT_ARGB); + BufferedImage image; + if (this.chart.containsGLPlot()) { + image = JOGLUtil.paintViewImage(this.chart, width, height, dpi); + } else { + image = new BufferedImage((int)(width * scaleFactor), (int)(height * scaleFactor), BufferedImage.TYPE_INT_ARGB); + } Graphics2D g = image.createGraphics(); AffineTransform at = g.getTransform(); at.scale(scaleFactor, scaleFactor); diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/EarthGLPlot.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/EarthGLPlot.java index fecc03ca..f330136a 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/EarthGLPlot.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/EarthGLPlot.java @@ -268,6 +268,8 @@ public class EarthGLPlot extends GLPlot { this.setLight(gl); + this.updateTextRender(this.xAxis.getTickLabelFont()); + //Draw graphics for (int m = 0; m < this.graphics.getNumGraphics(); m++) { Graphic graphic = this.graphics.get(m); @@ -314,6 +316,9 @@ public class EarthGLPlot extends GLPlot { //Draw title this.drawTitle(); + this.textRenderer.dispose(); + this.textRenderer = null; + gl.glFlush(); //Do screen-shot diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/GLPlot.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/GLPlot.java index cd111cf4..b9a4a217 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/GLPlot.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/GLPlot.java @@ -23,10 +23,7 @@ import org.meteoinfo.chart.jogl.tessellator.TessPolygon; import org.meteoinfo.chart.plot.GridLine; import org.meteoinfo.chart.plot.Plot; import org.meteoinfo.chart.plot.PlotType; -import org.meteoinfo.chart.render.jogl.JOGLGraphicRender; -import org.meteoinfo.chart.render.jogl.MeshRender; -import org.meteoinfo.chart.render.jogl.TriMeshRender; -import org.meteoinfo.chart.render.jogl.VolumeRender; +import org.meteoinfo.chart.render.jogl.*; import org.meteoinfo.chart.shape.TextureShape; import org.meteoinfo.common.*; import org.meteoinfo.common.colors.ColorMap; @@ -2444,87 +2441,121 @@ public class GLPlot extends Plot { } } - if (graphic.getNumGraphics() == 1) { - Graphic gg = graphic.getGraphicN(0); - this.drawGraphic(gl, gg); + if (graphic instanceof MeshGraphic) { + if (!this.renderMap.containsKey(graphic)) { + renderMap.put(graphic, new MeshRender(gl, (MeshGraphic) graphic)); + } + MeshRender meshRender = (MeshRender) renderMap.get(graphic); + meshRender.setTransform(this.transform, this.alwaysUpdateBuffers); + meshRender.setOrthographic(this.orthographic); + meshRender.setLighting(this.lighting); + meshRender.updateMatrix(); + meshRender.draw(); + } else if (graphic instanceof IsosurfaceGraphics) { + this.drawIsosurface(gl, (IsosurfaceGraphics) graphic); + } else if (graphic instanceof ParticleGraphics) { + this.drawParticles(gl, (ParticleGraphics) graphic); + } else if (graphic instanceof TriMeshGraphic) { + if (!this.renderMap.containsKey(graphic)) { + renderMap.put(graphic, new TriMeshRender(gl, (TriMeshGraphic) graphic)); + } + TriMeshRender triMeshRender = (TriMeshRender) renderMap.get(graphic); + triMeshRender.setTransform(this.transform, this.alwaysUpdateBuffers); + triMeshRender.setOrthographic(this.orthographic); + triMeshRender.setLighting(this.lighting); + triMeshRender.updateMatrix(); + triMeshRender.draw(); + } else if (graphic instanceof VolumeGraphic) { + try { + if (this.clipPlane) + this.disableClipPlane(gl); + if (!this.renderMap.containsKey(graphic)) { + renderMap.put(graphic, new VolumeRender(gl, (VolumeGraphic) graphic)); + } + VolumeRender volumeRender = (VolumeRender) renderMap.get(graphic); + volumeRender.setTransform(this.transform, this.alwaysUpdateBuffers); + volumeRender.setOrthographic(this.orthographic); + volumeRender.updateMatrix(); + volumeRender.draw(); + if (this.clipPlane) + this.enableClipPlane(gl); + } catch (Exception e) { + e.printStackTrace(); + } } else { - if (graphic instanceof MeshGraphic) { - //this.drawSurface(gl, (SurfaceGraphics) graphic); - if (!this.renderMap.containsKey(graphic)) { - renderMap.put(graphic, new MeshRender(gl, (MeshGraphic) graphic)); - } - MeshRender meshRender = (MeshRender) renderMap.get(graphic); - meshRender.setTransform(this.transform, this.alwaysUpdateBuffers); - meshRender.setOrthographic(this.orthographic); - meshRender.setLighting(this.lighting); - meshRender.updateMatrix(); - meshRender.draw(); - } else if (graphic instanceof IsosurfaceGraphics) { - this.drawIsosurface(gl, (IsosurfaceGraphics) graphic); - } else if (graphic instanceof ParticleGraphics) { - this.drawParticles(gl, (ParticleGraphics) graphic); - } else if (graphic instanceof TriMeshGraphic) { - if (!this.renderMap.containsKey(graphic)) { - renderMap.put(graphic, new TriMeshRender(gl, (TriMeshGraphic) graphic)); - } - TriMeshRender triMeshRender = (TriMeshRender) renderMap.get(graphic); - triMeshRender.setTransform(this.transform, this.alwaysUpdateBuffers); - triMeshRender.setOrthographic(this.orthographic); - triMeshRender.setLighting(this.lighting); - triMeshRender.updateMatrix(); - triMeshRender.draw(); - } else if (graphic instanceof VolumeGraphic) { - try { - if (this.clipPlane) - this.disableClipPlane(gl); - if (!this.renderMap.containsKey(graphic)) { - renderMap.put(graphic, new VolumeRender(gl, (VolumeGraphic) graphic)); - } - VolumeRender volumeRender = (VolumeRender) renderMap.get(graphic); - volumeRender.setTransform(this.transform, this.alwaysUpdateBuffers); - volumeRender.setOrthographic(this.orthographic); - volumeRender.updateMatrix(); - volumeRender.draw(); - if (this.clipPlane) - this.enableClipPlane(gl); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - boolean isDraw = true; - if (graphic instanceof GraphicCollection3D) { - if (graphic.getNumGraphics() == 0) { + boolean isDraw = true; + if (graphic instanceof GraphicCollection3D) { + if (graphic.getNumGraphics() == 0) { + isDraw = false; + } else { + GraphicCollection3D gg = (GraphicCollection3D) graphic; + if (gg.isAllQuads()) { + this.drawQuadsPolygons(gl, gg); + isDraw = false; + } else if (gg.isAllTriangle()) { + this.drawTrianglePolygons(gl, gg); isDraw = false; - } else { - GraphicCollection3D gg = (GraphicCollection3D) graphic; - if (gg.isAllQuads()) { - this.drawQuadsPolygons(gl, gg); - isDraw = false; - } else if (gg.isAllTriangle()) { - this.drawTrianglePolygons(gl, gg); - isDraw = false; - } } } - if (isDraw) { - switch (graphic.getGraphicN(0).getShape().getShapeType()) { - case POINT_Z: - if (((GraphicCollection3D) graphic).isSphere()) { - this.drawSpheres(gl, graphic); - } else { - this.drawPoints(gl, graphic); + } + if (isDraw) { + switch (graphic.getGraphicN(0).getShape().getShapeType()) { + case POINT_Z: + if (((GraphicCollection3D) graphic).isSphere()) { + this.drawSpheres(gl, graphic); + } else { + this.drawPoints(gl, graphic); + } + break; + case POLYLINE_Z: + boolean useRender = true; + ColorBreak cb = graphic.getGraphicN(0).getLegend(); + if (cb instanceof StreamlineBreak) { + useRender = false; + } else if (cb instanceof ColorBreakCollection) { + if (((ColorBreakCollection) cb).get(0) instanceof StreamlineBreak) { + useRender = false; } - break; - default: + } + if (useRender) { + if (graphic.getGraphicN(0).getShape() instanceof PipeShape) { + if (!this.renderMap.containsKey(graphic)) { + renderMap.put(graphic, new PipeRender(gl, (GraphicCollection3D) graphic)); + } + PipeRender pipeRender = (PipeRender) renderMap.get(graphic); + pipeRender.setTransform(this.transform, this.alwaysUpdateBuffers); + pipeRender.setOrthographic(this.orthographic); + pipeRender.setLighting(this.lighting); + pipeRender.updateMatrix(); + pipeRender.draw(); + } else { + if (!this.renderMap.containsKey(graphic)) { + renderMap.put(graphic, new LineRender(gl, (GraphicCollection3D) graphic)); + } + LineRender lineRender = (LineRender) renderMap.get(graphic); + lineRender.setTransform(this.transform, this.alwaysUpdateBuffers); + lineRender.setOrthographic(this.orthographic); + lineRender.setLighting(this.lighting); + lineRender.updateMatrix(); + lineRender.draw(); + } + } else { for (int i = 0; i < graphic.getNumGraphics(); i++) { Graphic gg = graphic.getGraphicN(i); this.drawGraphic(gl, gg); } - break; - } + } + break; + default: + for (int i = 0; i < graphic.getNumGraphics(); i++) { + Graphic gg = graphic.getGraphicN(i); + this.drawGraphic(gl, gg); + } + break; } } } + if (graphic instanceof GraphicCollection3D) { if (lightEnabled && !((GraphicCollection3D)graphic).isUsingLight()) { this.lighting.start(gl); @@ -2878,7 +2909,7 @@ public class GLPlot extends Plot { Vector n1 = pipe.getNormal(i); Vector n2 = pipe.getNormal(i+1); gl.glBegin(GL_TRIANGLE_STRIP); - for(int j = 0; j < (int)c2.size(); ++j) + for(int j = 0; j < c2.size(); ++j) { gl.glNormal3fv(JOGLUtil.toArray(n2.get(j)), 0); gl.glVertex3fv(JOGLUtil.toArray(c2.get(j)), 0); diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/Pipe.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/Pipe.java index e97aae93..a2b4b328 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/Pipe.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/Pipe.java @@ -110,6 +110,14 @@ public class Pipe { return this.contours.size(); } + /** + * Get vertex number + * @return Vertex number + */ + public int getVertexCount() { + return this.path.size() * this.contour.size(); + } + /** * Get normal * @param idx Index diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/PipeShape.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/PipeShape.java index 26269053..f922e3fb 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/PipeShape.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/pipe/PipeShape.java @@ -60,6 +60,10 @@ public class PipeShape extends PolylineZShape { return this.steps; } + public int getVertexCount() { + return this.getPointNum() * (this.steps + 1); + } + void generatePipe() { Vector path = new Vector<>(); for (PointZ p : (List) this.getPoints()) { diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/LineRender.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/LineRender.java new file mode 100644 index 00000000..22439ea3 --- /dev/null +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/LineRender.java @@ -0,0 +1,198 @@ +package org.meteoinfo.chart.render.jogl; + +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GL2; +import com.jogamp.opengl.util.GLBuffers; +import com.jogamp.opengl.util.texture.awt.AWTTextureIO; +import org.meteoinfo.chart.graphic.GraphicCollection3D; +import org.meteoinfo.chart.jogl.Program; +import org.meteoinfo.chart.jogl.Transform; +import org.meteoinfo.chart.jogl.Utils; +import org.meteoinfo.geometry.graphic.Graphic; +import org.meteoinfo.geometry.legend.*; +import org.meteoinfo.geometry.shape.PointZ; +import org.meteoinfo.geometry.shape.Polyline; +import org.meteoinfo.geometry.shape.PolylineZ; +import org.meteoinfo.geometry.shape.PolylineZShape; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; + +import static com.jogamp.opengl.GL.GL_TEXTURE_2D; + +public class LineRender extends JOGLGraphicRender { + + private GraphicCollection3D graphics; + private IntBuffer vbo; + private Program program; + private int vertexNum; + private int sizePosition; + private int sizeColor; + private int sizeNormal; + private float[] vertexColor; + private float lineWidth = 1.0f; + private List linePointNumbers; + + /** + * Constructor + * + * @param gl The JOGL GL2 object + */ + public LineRender(GL2 gl) { + super(gl); + + if (useShader) { + try { + this.compileShaders(); + } catch (Exception e) { + e.printStackTrace(); + } + } + initVertexBuffer(); + } + + /** + * Constructor + * + * @param gl The JOGL GL2 object + * @param graphics Linestring 3D graphics + */ + public LineRender(GL2 gl, GraphicCollection3D graphics) { + this(gl); + + this.graphics = graphics; + this.updateVertexColor(); + } + + void compileShaders() throws Exception { + String vertexShaderCode = Utils.loadResource("/shaders/surface/vertex.vert"); + String fragmentShaderCode = Utils.loadResource("/shaders/surface/surface.frag"); + program = new Program("surface", vertexShaderCode, fragmentShaderCode); + } + + private void initVertexBuffer() { + vbo = GLBuffers.newDirectIntBuffer(1); + } + + private void updateVertexColor() { + this.vertexNum = 0; + for (Graphic graphic : this.graphics.getGraphics()) { + this.vertexNum += graphic.getShape().getPointNum(); + } + + this.vertexColor = new float[this.vertexNum * 4]; + int i = 0; + float[] color; + for (Graphic graphic : this.graphics.getGraphics()) { + int n = graphic.getShape().getPointNum(); + ColorBreak cb = graphic.getLegend(); + if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) { + PolylineBreak lineBreak; + for (int j = 0; j < n; j++) { + lineBreak = (PolylineBreak) ((ColorBreakCollection) cb).get(j); + this.lineWidth = lineBreak.getWidth(); + color = lineBreak.getColor().getRGBComponents(null); + System.arraycopy(color, 0, vertexColor, i * 4, 4); + i++; + } + } else { + this.lineWidth = ((PolylineBreak) cb).getWidth(); + color = cb.getColor().getRGBComponents(null); + for (int j = 0; j < n; j++) { + System.arraycopy(color, 0, vertexColor, i * 4, 4); + i++; + } + } + } + } + + private float[] getVertexPosition() { + float[] vertexData = new float[this.vertexNum * 3]; + int i = 0; + linePointNumbers = new ArrayList<>(); + for (Graphic graphic : this.graphics.getGraphics()) { + PolylineZShape shape = (PolylineZShape) graphic.getShape(); + for (Polyline line : shape.getPolylines()) { + List ps = (List) line.getPointList(); + linePointNumbers.add(ps.size()); + for (PointZ p : ps) { + vertexData[i] = transform.transform_x((float) p.X); + vertexData[i + 1] = transform.transform_y((float) p.Y); + vertexData[i + 2] = transform.transform_z((float) p.Z); + i += 3; + } + } + } + + return vertexData; + } + + @Override + public void setTransform(Transform transform, boolean alwaysUpdateBuffers) { + boolean updateBuffer = true; + if (!alwaysUpdateBuffers && this.transform != null && this.transform.equals(transform)) + updateBuffer = false; + + super.setTransform((Transform) transform.clone()); + + if (updateBuffer) { + float[] vertexData = this.getVertexPosition(); + FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData); + sizePosition = vertexBuffer.capacity() * Float.BYTES; + + FloatBuffer colorBuffer = GLBuffers.newDirectFloatBuffer(vertexColor); + sizeColor = colorBuffer.capacity() * Float.BYTES; + int totalSize = sizePosition + sizeColor; + + gl.glGenBuffers(1, vbo); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0)); + gl.glBufferData(GL.GL_ARRAY_BUFFER, totalSize, null, GL.GL_STATIC_DRAW); + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, sizePosition, vertexBuffer); + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizePosition, sizeColor, colorBuffer); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); + } + } + + void setUniforms() { + + } + + @Override + public void draw() { + if (useShader) { // not working now + program.use(gl); + setUniforms(); + + gl.glUseProgram(0); + } else { + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0)); + + // enable vertex arrays + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + gl.glColorPointer(4, GL.GL_FLOAT, 0, sizePosition); + + boolean lightEnabled = this.lighting.isEnable(); + if (lightEnabled) { + this.lighting.stop(gl); + } + gl.glLineWidth(this.lineWidth * this.dpiScale); + int sIdx = 0; + for (int np : linePointNumbers) { + gl.glDrawArrays(GL.GL_LINE_STRIP, sIdx, np); + sIdx += np; + } + if (lightEnabled) { + this.lighting.start(gl); + } + + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); + } + } +} diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/PipeRender.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/PipeRender.java new file mode 100644 index 00000000..37b24816 --- /dev/null +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/PipeRender.java @@ -0,0 +1,263 @@ +package org.meteoinfo.chart.render.jogl; + +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GL2; +import com.jogamp.opengl.util.GLBuffers; +import org.joml.Vector3f; +import org.meteoinfo.chart.graphic.GraphicCollection3D; +import org.meteoinfo.chart.jogl.Program; +import org.meteoinfo.chart.jogl.Transform; +import org.meteoinfo.chart.jogl.Utils; +import org.meteoinfo.chart.jogl.pipe.Pipe; +import org.meteoinfo.chart.jogl.pipe.PipeShape; +import org.meteoinfo.geometry.graphic.Graphic; +import org.meteoinfo.geometry.legend.BreakTypes; +import org.meteoinfo.geometry.legend.ColorBreak; +import org.meteoinfo.geometry.legend.ColorBreakCollection; +import org.meteoinfo.geometry.legend.PolylineBreak; +import org.meteoinfo.geometry.shape.PointZ; +import org.meteoinfo.geometry.shape.Polyline; +import org.meteoinfo.geometry.shape.PolylineZShape; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +public class PipeRender extends JOGLGraphicRender{ + + private GraphicCollection3D graphics; + private IntBuffer vbo; + private Program program; + private int vertexNum; + private int sizePosition; + private int sizeColor; + private int sizeNormal; + private float[] vertexColor; + private int[] vertexIndices; + private List linePointNumbers; + + /** + * Constructor + * + * @param gl The JOGL GL2 object + */ + public PipeRender(GL2 gl) { + super(gl); + + if (useShader) { + try { + this.compileShaders(); + } catch (Exception e) { + e.printStackTrace(); + } + } + initVertexBuffer(); + } + + /** + * Constructor + * + * @param gl The JOGL GL2 object + * @param graphics Linestring 3D graphics + */ + public PipeRender(GL2 gl, GraphicCollection3D graphics) { + this(gl); + + this.graphics = graphics; + this.vertexNum = 0; + for (Graphic graphic : this.graphics.getGraphics()) { + this.vertexNum += ((PipeShape) graphic.getShape()).getVertexCount(); + } + } + + void compileShaders() throws Exception { + String vertexShaderCode = Utils.loadResource("/shaders/surface/vertex.vert"); + String fragmentShaderCode = Utils.loadResource("/shaders/surface/surface.frag"); + program = new Program("surface", vertexShaderCode, fragmentShaderCode); + } + + private void initVertexBuffer() { + vbo = GLBuffers.newDirectIntBuffer(2); + } + + private void updateVertexColor() { + this.vertexColor = new float[this.vertexNum * 4]; + int i = 0; + float[] color; + for (Graphic graphic : this.graphics.getGraphics()) { + PipeShape shape = (PipeShape) graphic.getShape(); + Pipe pipe = shape.getPipe(); + int n = pipe.getContourCount(); + int m = pipe.getContour().size(); + ColorBreak cb = graphic.getLegend(); + if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) { + ColorBreak lineBreak; + for (int j = 0; j < n; j++) { + lineBreak = ((ColorBreakCollection) cb).get(j); + color = lineBreak.getColor().getRGBComponents(null); + for (int k = 0; k < m; k++) { + System.arraycopy(color, 0, vertexColor, i * 4, 4); + i++; + } + } + } else { + color = cb.getColor().getRGBComponents(null); + for (int j = 0; j < n * m; j++) { + System.arraycopy(color, 0, vertexColor, i * 4, 4); + i++; + } + } + } + } + + private float[] getVertexPosition() { + float[] vertexData = new float[this.vertexNum * 3]; + int i = 0; + linePointNumbers = new ArrayList<>(); + for (Graphic graphic : this.graphics.getGraphics()) { + PipeShape shape = (PipeShape) graphic.getShape(); + shape.transform(transform); + Pipe pipe = shape.getPipe(); + linePointNumbers.add(pipe.getVertexCount()); + for (int j = 0; j < pipe.getContourCount(); j++) { + for (Vector3f vector3f : shape.getPipe().getContour(j)) { + vertexData[i] = vector3f.x; + vertexData[i + 1] = vector3f.y; + vertexData[i + 2] = vector3f.z; + i += 3; + } + } + } + + return vertexData; + } + + private void updateVertexIndices() { + int idxNum = 0; + for (Graphic graphic : this.graphics.getGraphics()) { + PipeShape shape = (PipeShape) graphic.getShape(); + Pipe pipe = shape.getPipe(); + idxNum += (pipe.getContourCount() - 1) * (pipe.getContour().size() - 1) * 6; + } + + vertexIndices = new int[idxNum]; + int i = 0; + int b = 0; + for (Graphic graphic : this.graphics.getGraphics()) { + PipeShape shape = (PipeShape) graphic.getShape(); + Pipe pipe = shape.getPipe(); + int n = pipe.getContour().size(); + for (int j = 0; j < pipe.getContourCount() - 1; j++) { + Vector c1 = pipe.getContour(j); + Vector c2 = pipe.getContour(j + 1); + for (int k = 0; k < n - 1; k++) { + vertexIndices[i++] = b + j * n + k; + vertexIndices[i++] = b + j * n + k + 1; + vertexIndices[i++] = b + (j + 1) * n + k; + + vertexIndices[i++] = b + j * n + k + 1; + vertexIndices[i++] = b + (j + 1) * n + k + 1; + vertexIndices[i++] = b + (j + 1) * n + k; + } + } + b += pipe.getVertexCount(); + } + } + + private float[] getVertexNormal() { + float[] vertexNormal = new float[this.vertexNum * 3]; + int i = 0; + for (Graphic graphic : this.graphics.getGraphics()) { + PipeShape shape = (PipeShape) graphic.getShape(); + Pipe pipe = shape.getPipe(); + for (int j = 0; j < pipe.getContourCount(); j++) { + for (Vector3f vector3f : shape.getPipe().getNormal(j)) { + vertexNormal[i] = vector3f.x; + vertexNormal[i + 1] = vector3f.y; + vertexNormal[i + 2] = vector3f.z; + i += 3; + } + } + } + + return vertexNormal; + } + + @Override + public void setTransform(Transform transform, boolean alwaysUpdateBuffers) { + boolean updateBuffer = true; + if (!alwaysUpdateBuffers && this.transform != null && this.transform.equals(transform)) + updateBuffer = false; + + super.setTransform((Transform) transform.clone()); + + if (updateBuffer) { + float[] vertexData = this.getVertexPosition(); + FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData); + sizePosition = vertexBuffer.capacity() * Float.BYTES; + + float[] vertexNormal = this.getVertexNormal(); + FloatBuffer normalBuffer = GLBuffers.newDirectFloatBuffer(vertexNormal); + sizeNormal = normalBuffer.capacity() * Float.BYTES; + + if (vertexColor == null) { + this.updateVertexColor(); + } + FloatBuffer colorBuffer = GLBuffers.newDirectFloatBuffer(vertexColor); + sizeColor = colorBuffer.capacity() * Float.BYTES; + int totalSize = sizePosition + sizeNormal + sizeColor; + + gl.glGenBuffers(2, vbo); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0)); + gl.glBufferData(GL.GL_ARRAY_BUFFER, totalSize, null, GL.GL_STATIC_DRAW); + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, sizePosition, vertexBuffer); + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizePosition, sizeNormal, normalBuffer); + gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizePosition + sizeNormal, sizeColor, colorBuffer); + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); + + if (vertexIndices == null) { + this.updateVertexIndices(); + } + IntBuffer indexBuffer = GLBuffers.newDirectIntBuffer(vertexIndices); + gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo.get(1)); + gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * Integer.BYTES, indexBuffer, GL.GL_STATIC_DRAW); + gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); + } + } + + void setUniforms() { + + } + + @Override + public void draw() { + if (useShader) { // not working now + program.use(gl); + setUniforms(); + + gl.glUseProgram(0); + } else { + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0)); + gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo.get(1)); + + // enable vertex arrays + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); + gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); + gl.glNormalPointer(GL.GL_FLOAT, 0, sizePosition); + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + gl.glColorPointer(4, GL.GL_FLOAT, 0, sizePosition + sizeNormal); + + gl.glDrawElements(GL2.GL_TRIANGLES, vertexIndices.length, GL.GL_UNSIGNED_INT, 0); + + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); + gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); + gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); + } + } +} diff --git a/meteoinfo-geo/meteoinfo-geo.iml b/meteoinfo-geo/meteoinfo-geo.iml index 49d4882b..7398874d 100644 --- a/meteoinfo-geo/meteoinfo-geo.iml +++ b/meteoinfo-geo/meteoinfo-geo.iml @@ -12,19 +12,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - @@ -33,28 +65,15 @@ - - - - - - - - - - - - - @@ -70,7 +89,6 @@ - @@ -86,49 +104,31 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/analysis/GeometryUtil.java b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/analysis/GeometryUtil.java index 19e47e3c..73e60e52 100644 --- a/meteoinfo-geo/src/main/java/org/meteoinfo/geo/analysis/GeometryUtil.java +++ b/meteoinfo-geo/src/main/java/org/meteoinfo/geo/analysis/GeometryUtil.java @@ -800,7 +800,7 @@ public class GeometryUtil { } if (isZ) { - return new Array[]{xArray, yArray, zArray}; + return new Array[]{xArray, yArray, zArray, mArray}; } else { return new Array[]{xArray, yArray}; } diff --git a/meteoinfo-lab/milconfig.xml b/meteoinfo-lab/milconfig.xml index 635cb15d..916aa9e1 100644 --- a/meteoinfo-lab/milconfig.xml +++ b/meteoinfo-lab/milconfig.xml @@ -1,32 +1,32 @@ - - - - - - - - - - + - + + + + + + + + + + - + - + diff --git a/meteoinfo-lab/pylib/mipylib/numeric/core/_ndarray.py b/meteoinfo-lab/pylib/mipylib/numeric/core/_ndarray.py index a8fb76df..cdf985f5 100644 --- a/meteoinfo-lab/pylib/mipylib/numeric/core/_ndarray.py +++ b/meteoinfo-lab/pylib/mipylib/numeric/core/_ndarray.py @@ -6,7 +6,7 @@ NDArray class - multiple dimensional array from org.meteoinfo.data import GridArray from org.meteoinfo.ndarray.math import ArrayMath, ArrayUtil from org.meteoinfo.math.linalg import LinalgUtil -from org.meteoinfo.ndarray import Array, Range, MAMath, Complex +from org.meteoinfo.ndarray import Array, Range, MAMath, Complex, DataType import datetime @@ -20,7 +20,7 @@ class NDArray(object): if not isinstance(array, Array): array = ArrayUtil.array(array, None) - if array.getRank() == 0: + if array.getRank() == 0 and array.getDataType() != DataType.STRUCTURE: array = ArrayUtil.array([array.getIndexIterator().getObjectNext()]) self._array = array diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class index 7baa6fbf..98498494 100644 Binary files a/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class and b/meteoinfo-lab/pylib/mipylib/plotlib/miplot$py.class differ diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py index 4d68dd57..76a43ec5 100644 --- a/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py +++ b/meteoinfo-lab/pylib/mipylib/plotlib/miplot.py @@ -974,7 +974,7 @@ def savefig(fname, width=None, height=None, dpi=None, sleep=None): Save the current figure. :param fname: (*string*) A string containing a path to a filename. The output format - is deduced from the extention of the filename. Supported format: 'png', 'bmp', + is deduced from the extension of the filename. Supported format: 'png', 'bmp', 'jpg', 'gif', 'tif', 'eps' and 'pdf'. :param width: (*int*) Optional, width of the output figure with pixel units. Default is None, the output figure size is same as *figures* window. @@ -2129,7 +2129,7 @@ def gifanimation(filename, repeat=0, delay=1000): def gifaddframe(animation, width=None, height=None, dpi=None): """ - Add a frame to an gif animation object + Add a frame to a gif animation object :param animation: Gif animation object :param width: (*int*) Image width diff --git a/meteoinfo-map/config.xml b/meteoinfo-map/config.xml index b9693bdd..6e50fc10 100644 --- a/meteoinfo-map/config.xml +++ b/meteoinfo-map/config.xml @@ -1,6 +1,6 @@ - + diff --git a/meteoinfo-map/default.mip b/meteoinfo-map/default.mip index eb142490..af14e48a 100644 --- a/meteoinfo-map/default.mip +++ b/meteoinfo-map/default.mip @@ -2,15 +2,12 @@ - + - + - - - @@ -27,7 +24,7 @@ - +