1) {
+ vec2 clipSpacePointCoord = 2.0 * gl_PointCoord - 1.0;
+
+ if (uMarkerShape == 2) { // circle
+ float distance = length(clipSpacePointCoord);
+
+ if (distance > 1.0) {
+ discard;
+ }
+ } else if (uMarkerShape == 3) { // diamond
+ float distance = abs(clipSpacePointCoord.x) + abs(clipSpacePointCoord.y);
+
+ if (distance > 1.0) {
+ discard;
+ }
+ } else if (uMarkerShape == 4) { // triangle
+ float x = clipSpacePointCoord.x;
+ float y = clipSpacePointCoord.y;
+ float distance = 2.0 * x - 1.0;
+ float distance2 = -2.0 * x - 1.0;
+
+ if (distance > y || distance2 > y) {
+ discard;
+ }
+ }
+
+ }
+ }
+ `;
+
+ const VERTEX_SHADER = `
+ attribute vec2 aVertexPosition;
+ uniform vec2 uDimensions;
+ uniform vec2 uOrigin;
+ uniform float uPointSize;
+
+ void main(void) {
+ gl_Position = vec4(2.0 * ((aVertexPosition - uOrigin) / uDimensions) - vec2(1,1), 0, 1);
+ gl_PointSize = uPointSize;
+ }
+ `;
/**
* Create a draw api utilizing WebGL.
@@ -90,6 +124,7 @@ define([
this.vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(this.vertexShader, VERTEX_SHADER);
this.gl.compileShader(this.vertexShader);
+
this.fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(this.fragmentShader, FRAGMENT_SHADER);
this.gl.compileShader(this.fragmentShader);
@@ -105,6 +140,7 @@ define([
// shader programs (to pass values into shaders at draw-time)
this.aVertexPosition = this.gl.getAttribLocation(this.program, "aVertexPosition");
this.uColor = this.gl.getUniformLocation(this.program, "uColor");
+ this.uMarkerShape = this.gl.getUniformLocation(this.program, "uMarkerShape");
this.uDimensions = this.gl.getUniformLocation(this.program, "uDimensions");
this.uOrigin = this.gl.getUniformLocation(this.program, "uOrigin");
this.uPointSize = this.gl.getUniformLocation(this.program, "uPointSize");
@@ -114,9 +150,6 @@ define([
// Create a buffer to holds points which will be drawn
this.buffer = this.gl.createBuffer();
- // Use a line width of 2.0 for legibility
- this.gl.lineWidth(2.0);
-
// Enable blending, for smoothness
this.gl.enable(this.gl.BLEND);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
@@ -138,14 +171,18 @@ define([
((v - this.origin[1]) / this.dimensions[1]) * this.height;
};
- DrawWebGL.prototype.doDraw = function (drawType, buf, color, points) {
+ DrawWebGL.prototype.doDraw = function (drawType, buf, color, points, shape) {
if (this.isContextLost) {
return;
}
+
+ const shapeCode = MARKER_SHAPES[shape] ? MARKER_SHAPES[shape].drawWebGL : 0;
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, buf, this.gl.DYNAMIC_DRAW);
this.gl.vertexAttribPointer(this.aVertexPosition, 2, this.gl.FLOAT, false, 0, 0);
this.gl.uniform4fv(this.uColor, color);
+ this.gl.uniform1i(this.uMarkerShape, shapeCode)
this.gl.drawArrays(drawType, 0, points);
};
@@ -210,12 +247,12 @@ define([
* Draw the buffer as points.
*
*/
- DrawWebGL.prototype.drawPoints = function (buf, color, points, pointSize) {
+ DrawWebGL.prototype.drawPoints = function (buf, color, points, pointSize, shape) {
if (this.isContextLost) {
return;
}
this.gl.uniform1f(this.uPointSize, pointSize);
- this.doDraw(this.gl.POINTS, buf, color, points);
+ this.doDraw(this.gl.POINTS, buf, color, points, shape);
};
/**
diff --git a/src/plugins/plot/src/draw/MarkerShapes.js b/src/plugins/plot/src/draw/MarkerShapes.js
new file mode 100644
index 0000000000..3c2afe7f8f
--- /dev/null
+++ b/src/plugins/plot/src/draw/MarkerShapes.js
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+define([], function () {
+ /**
+ * @label string (required) display name of shape
+ * @drawWebGL integer (unique, required) index provided to WebGL Fragment Shader
+ * @drawC2D function (required) canvas2d draw function
+ */
+ const MARKER_SHAPES = {
+ point: {
+ label: 'Point',
+ drawWebGL: 1,
+ drawC2D: function (x, y, size) {
+ const offset = size / 2;
+
+ this.c2d.fillRect(x - offset, y - offset, size, size);
+ }
+ },
+ circle: {
+ label: 'Circle',
+ drawWebGL: 2,
+ drawC2D: function (x, y, size) {
+ const radius = size / 2;
+
+ this.c2d.beginPath();
+ this.c2d.arc(x, y, radius, 0, 2 * Math.PI, false);
+ this.c2d.closePath();
+ this.c2d.fill();
+ }
+ },
+ diamond: {
+ label: 'Diamond',
+ drawWebGL: 3,
+ drawC2D: function (x, y, size) {
+ const offset = size / 2;
+ const top = [x, y + offset];
+ const right = [x + offset, y];
+ const bottom = [x, y - offset];
+ const left = [x - offset, y];
+
+ this.c2d.beginPath();
+ this.c2d.moveTo(...top);
+ this.c2d.lineTo(...right);
+ this.c2d.lineTo(...bottom);
+ this.c2d.lineTo(...left);
+ this.c2d.closePath();
+ this.c2d.fill();
+ }
+ },
+ triangle: {
+ label: 'Triangle',
+ drawWebGL: 4,
+ drawC2D: function (x, y, size) {
+ const offset = size / 2;
+ const v1 = [x, y - offset];
+ const v2 = [x - offset, y + offset];
+ const v3 = [x + offset, y + offset];
+
+ this.c2d.beginPath();
+ this.c2d.moveTo(...v1);
+ this.c2d.lineTo(...v2);
+ this.c2d.lineTo(...v3);
+ this.c2d.closePath();
+ this.c2d.fill();
+ }
+ }
+ };
+
+ return MARKER_SHAPES;
+});
diff --git a/src/plugins/plot/src/inspector/PlotSeriesFormController.js b/src/plugins/plot/src/inspector/PlotSeriesFormController.js
index d6b815c8f1..43335e403c 100644
--- a/src/plugins/plot/src/inspector/PlotSeriesFormController.js
+++ b/src/plugins/plot/src/inspector/PlotSeriesFormController.js
@@ -22,9 +22,11 @@
define([
'./PlotModelFormController',
+ '../draw/MarkerShapes',
'lodash'
], function (
PlotModelFormController,
+ MARKER_SHAPES,
_
) {
@@ -93,6 +95,13 @@ define([
value: o.key
};
});
+ this.$scope.markerShapeOptions = Object.entries(MARKER_SHAPES)
+ .map(([key, obj]) => {
+ return {
+ name: obj.label,
+ value: key
+ };
+ });
},
fields: [
@@ -108,6 +117,10 @@ define([
modelProp: 'markers',
objectPath: dynamicPathForKey('markers')
},
+ {
+ modelProp: 'markerShape',
+ objectPath: dynamicPathForKey('markerShape')
+ },
{
modelProp: 'markerSize',
coerce: Number,