From 4d5d7054e94e033a2c852ae4fda4c8aac0d2351e Mon Sep 17 00:00:00 2001 From: wyq Date: Thu, 21 Jul 2022 08:25:09 +0800 Subject: [PATCH] update volume shaders and add drawString3D function --- .../java/org/meteoinfo/chart/ChartText3D.java | 19 ++- .../org/meteoinfo/chart/jogl/Plot3DGL.java | 60 +++++++++- .../chart/render/jogl/VolumeRender.java | 4 +- .../main/resources/shaders/volume/basic.frag | 99 +++------------- .../resources/shaders/volume/maxValue.frag | 87 +++----------- .../resources/shaders/volume/specular.frag | 97 +++------------- .../resources/shaders/volume/volumeBase.glsl | 108 ++++++++++++++++++ .../org/meteoinfo/common/util/GlobalUtil.java | 2 +- .../geometry/graphic/GraphicCollection.java | 2 +- meteoinfo-lab/milconfig.xml | 24 ++-- .../pylib/mipylib/plotlib/_axes3d$py.class | Bin 88994 -> 89168 bytes .../pylib/mipylib/plotlib/_axes3d.py | 3 + 12 files changed, 244 insertions(+), 261 deletions(-) create mode 100644 meteoinfo-chart/src/main/resources/shaders/volume/volumeBase.glsl diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartText3D.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartText3D.java index 4610a50e..00ca02b2 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartText3D.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/ChartText3D.java @@ -23,7 +23,8 @@ import org.meteoinfo.geometry.shape.PointZ; */ public class ChartText3D extends ChartText { private double z; - private PointZ zdir = null; + private PointZ zdir = null; + private boolean draw3D = false; /** * Get z coordinate value @@ -89,6 +90,22 @@ public class ChartText3D extends ChartText { } this.setZDir(x1, y1, z1); } + + /** + * Get whether draw text at 3D location + * @return Boolean + */ + public boolean isDraw3D() { + return this.draw3D; + } + + /** + * Set whether draw text at 3D location + * @param value Boolean + */ + public void setDraw3D(boolean value) { + this.draw3D = value; + } /** * Set point diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java index 540153df..42925c0a 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/jogl/Plot3DGL.java @@ -1155,6 +1155,14 @@ public class Plot3DGL extends Plot implements GLEventListener { this.graphics.remove(this.graphics.size() - 1); } + /** + * Remove all graphics + */ + public void removeAllGraphics() { + this.graphics.clear(); + this.renderMap.clear(); + } + /** * Set auto extent */ @@ -1257,7 +1265,7 @@ public class Plot3DGL extends Plot implements GLEventListener { } //Draw text - for (int m = 0; m < this.graphics.getNumGraphics(); m++) { + /*for (int m = 0; m < this.graphics.getNumGraphics(); m++) { Graphic graphic = this.graphics.get(m); if (graphic.getNumGraphics() == 1) { Shape shape = graphic.getGraphicN(0).getShape(); @@ -1272,7 +1280,7 @@ public class Plot3DGL extends Plot implements GLEventListener { } } } - } + }*/ //Stop lighting if (this.lighting.isEnable()) { @@ -2363,6 +2371,37 @@ public class Plot3DGL extends Plot implements GLEventListener { return rect; } + Rectangle2D drawString3D(GL2 gl, ChartText3D text3D, float vx, float vy, float vz) { + return drawString3D(gl, text3D.getText(), text3D.getFont(), text3D.getColor(), vx, vy, vz); + } + + Rectangle2D drawString3D(GL2 gl, String str, Font font, Color color, float vx, float vy, float vz) { + //Get screen coordinates + Vector2f coord = this.toScreen(vx, vy, vz); + float x = coord.x; + float y = coord.y; + + //Rendering text string + TextRenderer textRenderer; + if (this.dpiScale == 1) { + textRenderer = new TextRenderer(font, true, true); + } else { + textRenderer = new TextRenderer(new Font(font.getFontName(), font.getStyle(), + (int)(font.getSize() * (1 + (this.dpiScale - 1) * 0.8))), true, true); + } + textRenderer.beginRendering(this.width, this.height, false); + //textRenderer.begin3DRendering(); + textRenderer.setColor(color); + textRenderer.setSmoothing(true); + Rectangle2D rect = textRenderer.getBounds(str.subSequence(0, str.length())); + textRenderer.draw3D(str, x, y, vz, 1.0f); + //textRenderer.draw3D(str, vx, vy, vz, 1.0f); + textRenderer.endRendering(); + //textRenderer.end3DRendering(); + + return rect; + } + void drawTitle() { if (title != null) { //Rendering text string @@ -2486,7 +2525,11 @@ public class Plot3DGL extends Plot implements GLEventListener { this.drawPoint(gl, graphic); break; case TEXT: - //this.drawText(gl, (ChartText3D) shape); + if (this.clipPlane) + this.disableClipPlane(gl); + this.drawText(gl, (ChartText3D) shape); + if (this.clipPlane) + this.enableClipPlane(gl); break; case POLYLINE: case POLYLINE_Z: @@ -2543,7 +2586,16 @@ public class Plot3DGL extends Plot implements GLEventListener { protected void drawText(GL2 gl, ChartText3D text) { Vector3f xyz = this.transform.transform((float) text.getX(), (float) text.getY(), (float) text.getZ()); - this.drawString(gl, text, xyz.x, xyz.y, xyz.z, text.getXAlign(), text.getYAlign()); + if (text.isDraw3D()) { + this.drawString3D(gl, text, xyz.x, xyz.y, xyz.z); + } else { + this.drawString(gl, text, xyz.x, xyz.y, xyz.z, text.getXAlign(), text.getYAlign()); + } + } + + protected void drawText3D(GL2 gl, ChartText3D text) { + Vector3f xyz = this.transform.transform((float) text.getX(), (float) text.getY(), (float) text.getZ()); + this.drawString3D(gl, text, xyz.x, xyz.y, xyz.z); } private void drawPoint(GL2 gl, Graphic graphic) { diff --git a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/VolumeRender.java b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/VolumeRender.java index 3b22b6e1..93db9ed0 100644 --- a/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/VolumeRender.java +++ b/meteoinfo-chart/src/main/java/org/meteoinfo/chart/render/jogl/VolumeRender.java @@ -323,7 +323,7 @@ public class VolumeRender extends JOGLGraphicRender { gl.glBindTexture(GL_TEXTURE_3D, this.normalsTexture); } - gl.glDisable(GL_DEPTH_TEST); + //gl.glDisable(GL_DEPTH_TEST); gl.glDrawArrays(GL_TRIANGLES, 0, volume.getVertexNumber()); // Starting from vertex 0; 3 vertices total -> 1 triangle @@ -335,7 +335,7 @@ public class VolumeRender extends JOGLGraphicRender { gl.glBindTexture(GL_TEXTURE_3D, 0); //Program.destroyAllPrograms(gl); gl.glUseProgram(0); - gl.glEnable(GL_DEPTH_TEST); + //gl.glEnable(GL_DEPTH_TEST); } catch (Exception e) { e.printStackTrace(); } diff --git a/meteoinfo-chart/src/main/resources/shaders/volume/basic.frag b/meteoinfo-chart/src/main/resources/shaders/volume/basic.frag index f6e64067..bd2f0b84 100644 --- a/meteoinfo-chart/src/main/resources/shaders/volume/basic.frag +++ b/meteoinfo-chart/src/main/resources/shaders/volume/basic.frag @@ -5,6 +5,7 @@ #define mgl_FragColor gl_FragColor #endif +uniform mat4 MVP; uniform vec2 viewSize; uniform mat4 iV; uniform mat4 iP; @@ -16,91 +17,9 @@ uniform vec3 aabbMin; uniform vec3 aabbMax; uniform bool orthographic; - uniform float brightness; -struct Ray { - vec3 origin; - vec3 direction; - vec3 inv_direction; - int sign[3]; -}; - -Ray makeRay(vec3 origin, vec3 direction) { - vec3 inv_direction = vec3(1.0) / direction; - int sign[3]; - sign[0] = inv_direction.x < 0.0 ? 1 : 0; - sign[1] = inv_direction.y < 0.0 ? 1 : 0; - sign[2] = inv_direction.z < 0.0 ? 1 : 0; - - return Ray( - origin, - direction, - inv_direction, - sign - ); -} - -Ray createRayOrthographic(vec2 uv) -{ - float far = 5.0; - - // Transform the camera origin to world space - vec4 origin = iP * vec4(uv, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, far, 1.0); - // Transform the direction from camera to world space and normalize - image = iV* image; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -Ray createRayPerspective(vec2 uv) -{ - // Transform the camera origin to world space - vec4 origin = iP * vec4(0.0, 0.0, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, 1.0, 1.0); - // Transform the direction from camera to world space and normalize - image = iV * image; - image = image / image.w; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -void intersect( - in Ray ray, in vec3 aabb[2], - out float tmin, out float tmax -){ - float tymin, tymax, tzmin, tzmax; - tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tmin = max(max(tmin, tymin), tzmin); - tmax = min(min(tmax, tymax), tzmax); -} - -vec4 premultiplyAlpha(vec4 color) -{ - //return vec4(color.rgb * color.a, color.a); - return color * color.a; -} - -// GL_ONE_MINUS_DST_ALPHA, GL_ONE -void blendToBack(inout vec4 accum, vec4 color) -{ - //accum = color * color.a * (1-accum.a) + accum; - accum = premultiplyAlpha(color) * (1.0 - accum.a) + accum; -} +#include volumeBase.glsl void main(){ vec2 vUV = 2.0 * (gl_FragCoord.xy + vec2(0.5, 0.5)) / viewSize - 1.0; @@ -131,7 +50,7 @@ void main(){ float px = 0.0; vec4 pxColor = vec4(0.0, 0.0, 0.0, 0.0); vec3 texCo = vec3(0.0, 0.0, 0.0); - + float tt = tmin; for(int count = 0; count < sampleCount; count++){ texCo = mix(end, start, float(count) / float(sampleCount));// - originOffset; @@ -145,11 +64,19 @@ void main(){ //value = value + pxColor - pxColor * value.a; blendToBack(value, pxColor); - if(value.a >= 0.95){ - value.a = 1.0; + if (tt == tmin && pxColor.a > 0.01) { + tt = tmax - float(count)/float(sampleCount)*(tmax - tmin); + } + + if (value.a >= 0.95) { break; } } mgl_FragColor = value * brightness; + + gl_FragDepth = calculateDepth(ray.origin + ray.direction * tt); + if (value.a < 0.01) { + gl_FragDepth = 1.0; + } } \ No newline at end of file diff --git a/meteoinfo-chart/src/main/resources/shaders/volume/maxValue.frag b/meteoinfo-chart/src/main/resources/shaders/volume/maxValue.frag index 01365f96..aaa3a71a 100644 --- a/meteoinfo-chart/src/main/resources/shaders/volume/maxValue.frag +++ b/meteoinfo-chart/src/main/resources/shaders/volume/maxValue.frag @@ -5,6 +5,7 @@ #define mgl_FragColor gl_FragColor #endif +uniform mat4 MVP; uniform vec2 viewSize; uniform mat4 iV; uniform mat4 iP; @@ -19,75 +20,7 @@ uniform bool orthographic; uniform float brightness; -struct Ray { - vec3 origin; - vec3 direction; - vec3 inv_direction; - int sign[3]; -}; - -Ray makeRay(vec3 origin, vec3 direction) { - vec3 inv_direction = vec3(1.0) / direction; - int sign[3]; - sign[0] = inv_direction.x < 0.0 ? 1 : 0; - sign[1] = inv_direction.y < 0.0 ? 1 : 0; - sign[2] = inv_direction.z < 0.0 ? 1 : 0; - - return Ray( - origin, - direction, - inv_direction, - sign - ); -} - -Ray createRayOrthographic(vec2 uv) -{ - float far = 5.0; - - // Transform the camera origin to world space - vec4 origin = iP * vec4(uv, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, far, 1.0); - // Transform the direction from camera to world space and normalize - image = iV* image; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -Ray createRayPerspective(vec2 uv) -{ - // Transform the camera origin to world space - vec4 origin = iP * vec4(0.0, 0.0, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, 1.0, 1.0); - // Transform the direction from camera to world space and normalize - image = iV * image; - image = image / image.w; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -void intersect( - in Ray ray, in vec3 aabb[2], - out float tmin, out float tmax -){ - float tymin, tymax, tzmin, tzmax; - tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tmin = max(max(tmin, tymin), tzmin); - tmax = min(min(tmax, tymax), tzmax); -} +#include volumeBase.glsl void main(){ vec2 vUV = 2.0 * (gl_FragCoord.xy + vec2(0.5, 0.5)) / viewSize - 1.0; @@ -116,13 +49,20 @@ void main(){ float px = 0.0; vec4 pxColor = vec4(0.0, 0.0, 0.0, 0.0); vec3 texCo = vec3(0.0, 0.0, 0.0); - + float tt = tmin; + float px0 = 0.0; for(int count = 0; count < sampleCount; count++){ - texCo = mix(start, end, float(count)/float(sampleCount));// - originOffset; + texCo = mix(end, start, float(count)/float(sampleCount));// - originOffset; px = max(px, texture3D(tex, texCo).r); + if (px > px0) { + tt = tmax - float(count)/float(sampleCount)*(tmax - tmin); + } + + px0 = px; + if(px >= 0.99){ break; } @@ -130,4 +70,9 @@ void main(){ pxColor = texture2D(colorMap, vec2(px, 0.0)); mgl_FragColor = pxColor * brightness; + + gl_FragDepth = calculateDepth(ray.origin + ray.direction * tt); + if (pxColor.a < 0.01) { + gl_FragDepth = 1.0; + } } \ No newline at end of file diff --git a/meteoinfo-chart/src/main/resources/shaders/volume/specular.frag b/meteoinfo-chart/src/main/resources/shaders/volume/specular.frag index 3c8c13b3..909e6597 100644 --- a/meteoinfo-chart/src/main/resources/shaders/volume/specular.frag +++ b/meteoinfo-chart/src/main/resources/shaders/volume/specular.frag @@ -5,6 +5,7 @@ #define mgl_FragColor gl_FragColor #endif +uniform mat4 MVP; uniform vec2 viewSize; uniform mat4 iV; uniform mat4 iP; @@ -20,94 +21,13 @@ uniform bool orthographic; uniform float brightness; +#include volumeBase.glsl + vec3 ambientLight = vec3(0.34, 0.32, 0.32); vec3 directionalLight = vec3(0.5, 0.5, 0.5); vec3 lightVector = normalize(vec3(-1.0, -1.0, 1.0)); vec3 specularColor = vec3(0.5, 0.5, 0.5); -struct Ray { - vec3 origin; - vec3 direction; - vec3 inv_direction; - int sign[3]; -}; - -Ray makeRay(vec3 origin, vec3 direction) { - vec3 inv_direction = vec3(1.0) / direction; - int sign[3]; - sign[0] = inv_direction.x < 0.0 ? 1 : 0; - sign[1] = inv_direction.y < 0.0 ? 1 : 0; - sign[2] = inv_direction.z < 0.0 ? 1 : 0; - - return Ray( - origin, - direction, - inv_direction, - sign - ); -} - -Ray createRayOrthographic(vec2 uv) -{ - float far = 5.0; - - // Transform the camera origin to world space - vec4 origin = iP * vec4(uv, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, far, 1.0); - // Transform the direction from camera to world space and normalize - image = iV* image; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -Ray createRayPerspective(vec2 uv) -{ - // Transform the camera origin to world space - vec4 origin = iP * vec4(0.0, 0.0, 0.0, 1.0); - origin = iV * origin; - origin = origin / origin.w; - - // Invert the perspective projection of the view-space position - vec4 image = iP * vec4(uv, 1.0, 1.0); - // Transform the direction from camera to world space and normalize - image = iV * image; - image = image / image.w; - vec4 direction = normalize(origin - image); - return makeRay(origin.xyz, direction.xyz); -} - -void intersect( - in Ray ray, in vec3 aabb[2], - out float tmin, out float tmax -){ - float tymin, tymax, tzmin, tzmax; - tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; - tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; - tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; - tmin = max(max(tmin, tymin), tzmin); - tmax = min(min(tmax, tymax), tzmax); -} - -vec4 premultiplyAlpha(vec4 color) -{ - //return vec4(color.rgb * color.a, color.a); - return color * color.a; -} - -// GL_ONE_MINUS_DST_ALPHA, GL_ONE -void blendToBack(inout vec4 accum, vec4 color) -{ - //accum = color * color.a * (1-accum.a) + accum; - accum = premultiplyAlpha(color) * (1.0 - accum.a) + accum; -} - void main(){ vec2 vUV = 2.0 * (gl_FragCoord.xy + vec2(0.5, 0.5)) / viewSize - 1.0; Ray ray; @@ -140,7 +60,7 @@ void main(){ vec3 texCo = vec3(0.0, 0.0, 0.0); vec3 normal = vec3(0.0, 0.0, 0.0); vec4 zero = vec4(0.0); - + float tt = tmin; for(int count = 0; count < sampleCount; count++){ texCo = mix(end, start, float(count)/float(sampleCount));// - originOffset; @@ -173,10 +93,19 @@ void main(){ //value = value + pxColor - pxColor*value.a; blendToBack(value, pxColor); + if (tt == tmin && pxColor.a > 0.01) { + tt = tmax - float(count)/float(sampleCount)*(tmax - tmin); + } + if(value.a >= 0.95){ break; } } mgl_FragColor = value * brightness; + + gl_FragDepth = calculateDepth(ray.origin + ray.direction * tt); + if (value.a < 0.01) { + gl_FragDepth = 1.0; + } } \ No newline at end of file diff --git a/meteoinfo-chart/src/main/resources/shaders/volume/volumeBase.glsl b/meteoinfo-chart/src/main/resources/shaders/volume/volumeBase.glsl new file mode 100644 index 00000000..ee1018b2 --- /dev/null +++ b/meteoinfo-chart/src/main/resources/shaders/volume/volumeBase.glsl @@ -0,0 +1,108 @@ + +struct Ray { + vec3 origin; + vec3 direction; + vec3 inv_direction; + int sign[3]; +}; + +Ray makeRay(vec3 origin, vec3 direction) { + vec3 inv_direction = vec3(1.0) / direction; + int sign[3]; + sign[0] = inv_direction.x < 0.0 ? 1 : 0; + sign[1] = inv_direction.y < 0.0 ? 1 : 0; + sign[2] = inv_direction.z < 0.0 ? 1 : 0; + + return Ray( + origin, + direction, + inv_direction, + sign + ); +} + +Ray createRay(vec2 uv) +{ + float far = 5.0; + + // Transform the camera origin to world space + vec4 origin = iP * vec4(uv, 0.0, 1.0); + origin = iV * origin; + origin = origin / origin.w; + + // Invert the perspective projection of the view-space position + vec4 image = iP * vec4(uv, far, 1.0); + // Transform the direction from camera to world space and normalize + image = iV* image; + vec4 direction = normalize(origin - image); + return makeRay(origin.xyz, direction.xyz); +} + +Ray createRayOrthographic(vec2 uv) +{ + float far = 5.0; + + // Transform the camera origin to world space + vec4 origin = iP * vec4(uv, 0.0, 1.0); + origin = iV * origin; + origin = origin / origin.w; + + // Invert the perspective projection of the view-space position + vec4 image = iP * vec4(uv, far, 1.0); + // Transform the direction from camera to world space and normalize + image = iV* image; + vec4 direction = normalize(origin - image); + return makeRay(origin.xyz, direction.xyz); +} + +Ray createRayPerspective(vec2 uv) +{ + // Transform the camera origin to world space + vec4 origin = iP * vec4(0.0, 0.0, 0.0, 1.0); + origin = iV * origin; + origin = origin / origin.w; + + // Invert the perspective projection of the view-space position + vec4 image = iP * vec4(uv, 1.0, 1.0); + // Transform the direction from camera to world space and normalize + image = iV * image; + image = image / image.w; + vec4 direction = normalize(origin - image); + return makeRay(origin.xyz, direction.xyz); +} + +void intersect( + in Ray ray, in vec3 aabb[2], + out float tmin, out float tmax +){ + float tymin, tymax, tzmin, tzmax; + tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; + tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.inv_direction.x; + tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; + tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.inv_direction.y; + tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; + tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.inv_direction.z; + tmin = max(max(tmin, tymin), tzmin); + tmax = min(min(tmax, tymax), tzmax); +} + +vec4 premultiplyAlpha(vec4 color) +{ + //return vec4(color.rgb * color.a, color.a); + return color * color.a; +} + +// GL_ONE_MINUS_DST_ALPHA, GL_ONE +void blendToBack(inout vec4 accum, vec4 color) +{ + //accum = color * color.a * (1-accum.a) + accum; + accum = premultiplyAlpha(color) * (1.0 - accum.a) + accum; +} + +float calculateDepth(vec3 pos) +{ + vec4 ndc = MVP * vec4(pos, 1.0); + ndc.xyz /= ndc.w; + return 0.5 * (gl_DepthRange.diff * ndc.z + (gl_DepthRange.near + gl_DepthRange.far)); + //return ndc.z * 0.5 + 0.5; +} diff --git a/meteoinfo-common/src/main/java/org/meteoinfo/common/util/GlobalUtil.java b/meteoinfo-common/src/main/java/org/meteoinfo/common/util/GlobalUtil.java index fb589285..fa57c9b9 100644 --- a/meteoinfo-common/src/main/java/org/meteoinfo/common/util/GlobalUtil.java +++ b/meteoinfo-common/src/main/java/org/meteoinfo/common/util/GlobalUtil.java @@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream; public static String getVersion(){ String version = GlobalUtil.class.getPackage().getImplementationVersion(); if (version == null || version.equals("")) { - version = "3.3.13"; + version = "3.3.14"; } return version; } diff --git a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/graphic/GraphicCollection.java b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/graphic/GraphicCollection.java index e30c2bea..903f300d 100644 --- a/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/graphic/GraphicCollection.java +++ b/meteoinfo-geometry/src/main/java/org/meteoinfo/geometry/graphic/GraphicCollection.java @@ -298,7 +298,7 @@ public class GraphicCollection extends Graphic implements Iterator { /** * Get graphic list size * - * @return Gaphic list size + * @return Graphic list size */ public int size() { return this.graphics.size(); diff --git a/meteoinfo-lab/milconfig.xml b/meteoinfo-lab/milconfig.xml index 58e1ce76..b5efbd6b 100644 --- a/meteoinfo-lab/milconfig.xml +++ b/meteoinfo-lab/milconfig.xml @@ -1,9 +1,6 @@ - - - - + @@ -16,17 +13,22 @@ + + + - - - + + + + - - - + + + + @@ -34,5 +36,5 @@
- + diff --git a/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class b/meteoinfo-lab/pylib/mipylib/plotlib/_axes3d$py.class index c7758e471b89e3b28beaabe9168db33630ae3643..b0fe7dae789ca02c592b0ef7f4300b390869e1e0 100644 GIT binary patch delta 10744 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 bPc&T|#dL)3(Q)$YbfnI7{JO5wQr-Jc50)C} delta 10641 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 DE