mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
update jogl scatter render
This commit is contained in:
parent
788ae3d51f
commit
df767d471f
@ -2504,7 +2504,16 @@ public class GLPlot extends Plot {
|
||||
if (((GraphicCollection3D) graphic).isSphere()) {
|
||||
this.drawSpheres(gl, graphic);
|
||||
} else {
|
||||
this.drawPoints(gl, graphic);
|
||||
//this.drawPoints(gl, graphic);
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new PointRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
PointRender pointRender = (PointRender) renderMap.get(graphic);
|
||||
pointRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
pointRender.setOrthographic(this.orthographic);
|
||||
pointRender.setLighting(this.lighting);
|
||||
pointRender.updateMatrix();
|
||||
pointRender.draw();
|
||||
}
|
||||
break;
|
||||
case POLYLINE_Z:
|
||||
|
||||
@ -1,11 +1,35 @@
|
||||
package org.meteoinfo.chart.render.jogl;
|
||||
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2;
|
||||
import com.jogamp.opengl.util.GLBuffers;
|
||||
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.PointZShape;
|
||||
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;
|
||||
|
||||
public class PointRender extends JOGLGraphicRender {
|
||||
|
||||
private GraphicCollection3D pointGraphics;
|
||||
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 pointSize;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -14,6 +38,15 @@ public class PointRender extends JOGLGraphicRender {
|
||||
*/
|
||||
public PointRender(GL2 gl) {
|
||||
super(gl);
|
||||
|
||||
if (useShader) {
|
||||
try {
|
||||
this.compileShaders();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
initVertexBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,12 +56,113 @@ public class PointRender extends JOGLGraphicRender {
|
||||
* @param pointGraphics 3D point graphics
|
||||
*/
|
||||
public PointRender(GL2 gl, GraphicCollection3D pointGraphics) {
|
||||
super(gl);
|
||||
this.pointGraphics = pointGraphics;
|
||||
this(gl);
|
||||
|
||||
this.graphics = pointGraphics;
|
||||
this.vertexNum = pointGraphics.getNumGraphics();
|
||||
PointBreak pb = (PointBreak) this.graphics.getGraphicN(0).getLegend();
|
||||
this.pointSize = pb.getSize();
|
||||
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.vertexColor = new float[this.vertexNum * 4];
|
||||
int i = 0;
|
||||
float[] color;
|
||||
for (Graphic graphic : this.graphics.getGraphics()) {
|
||||
PointBreak pb = (PointBreak) graphic.getLegend();
|
||||
color = pb.getColor().getRGBComponents(null);
|
||||
System.arraycopy(color, 0, vertexColor, i * 4, 4);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] getVertexPosition() {
|
||||
float[] vertexData = new float[this.vertexNum * 3];
|
||||
int i = 0;
|
||||
for (Graphic graphic : this.graphics.getGraphics()) {
|
||||
PointZShape shape = (PointZShape) graphic.getShape();
|
||||
PointZ p = (PointZ) shape.getPoint();
|
||||
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.glPointSize(this.pointSize * this.dpiScale);
|
||||
gl.glDrawArrays(GL.GL_POINTS, 0, this.vertexNum);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1326,7 +1326,7 @@ public class LayoutMap extends LayoutElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid label positiont
|
||||
* Set grid label position
|
||||
*
|
||||
* @param value Grid label position
|
||||
*/
|
||||
|
||||
@ -1,32 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\dataconvert">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\annotate"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\arrow"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\bar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\boxplot"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\toolbox"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\stats"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\dataframe">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\particles"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\scatter"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\model"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
|
||||
<RecentFolder Folder="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui"/>
|
||||
<RecentFolder Folder="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\toolbox\emips"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\dataconvert"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\geoshow"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\pie"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\main_gui.py"/>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\_reload.py"/>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\emission_panel.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\scatter\scatter3_4.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\dataframe\dataframe_groupby_3.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\main_gui.py"/>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\_reload.py"/>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\EMIPS\emips\gui\emission_panel.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\scatter\scatter3_4.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\dataframe\dataframe_groupby_3.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#-----------------------------------------------------
|
||||
# -----------------------------------------------------
|
||||
# Author: Yaqiang Wang
|
||||
# Date: 2018-7-18
|
||||
# Purpose: MeteoInfo index module
|
||||
# Note: Jython
|
||||
#-----------------------------------------------------
|
||||
# -----------------------------------------------------
|
||||
|
||||
from org.meteoinfo.dataframe import Index as MIIndex
|
||||
from org.meteoinfo.dataframe import DateTimeIndex as MIDateTimeIndex
|
||||
@ -15,8 +15,9 @@ import numbers
|
||||
import mipylib.numeric as np
|
||||
import mipylib.miutil as miutil
|
||||
|
||||
|
||||
class Index(object):
|
||||
|
||||
|
||||
@staticmethod
|
||||
def factory(data=None, name='Index', index=None):
|
||||
"""
|
||||
@ -32,7 +33,7 @@ class Index(object):
|
||||
return DateTimeIndex(index=index)
|
||||
else:
|
||||
return Index(index=index)
|
||||
|
||||
|
||||
def __init__(self, data=None, name='Index', index=None):
|
||||
"""
|
||||
Index
|
||||
@ -57,22 +58,22 @@ class Index(object):
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
self._index.setName(value)
|
||||
|
||||
|
||||
def __len__(self):
|
||||
return self._index.size()
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
provide iteration over the values of the Index
|
||||
"""
|
||||
return iter(self._index)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self._index.toString()
|
||||
|
||||
|
||||
def __getitem__(self, k):
|
||||
if isinstance(k, int):
|
||||
return self.data[k]
|
||||
@ -82,17 +83,17 @@ class Index(object):
|
||||
sidx = self.__len__() + sidx
|
||||
eidx = self.__len__() if k.stop is None else k.stop
|
||||
if eidx < 0:
|
||||
eidx = self.__len__() + eidx
|
||||
eidx = self.__len__() + eidx
|
||||
step = 1 if k.step is None else k.step
|
||||
r = self._index.subIndex(sidx, eidx, step)
|
||||
return Index.factory(index=r)
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, numbers.Number):
|
||||
return np.NDArray(self._index.equal(other))
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def index(self, v):
|
||||
"""
|
||||
Get index of a value.
|
||||
@ -120,14 +121,14 @@ class Index(object):
|
||||
r = self._index.getIndices(key.asarray())
|
||||
else:
|
||||
r = self._index.getIndices(key)
|
||||
if outkeys:
|
||||
if outkeys:
|
||||
return list(r[0]), list(r[1])
|
||||
else:
|
||||
return list(r[0])
|
||||
|
||||
|
||||
def fill_keylist(self, rdata, rfdata):
|
||||
return self._index.fillKeyList(rdata.asarray(), rfdata)
|
||||
|
||||
|
||||
def get_format(self):
|
||||
"""
|
||||
Get value to string format.
|
||||
@ -135,7 +136,7 @@ class Index(object):
|
||||
:returns: (*string*) Format string.
|
||||
"""
|
||||
return self._index.getFormat()
|
||||
|
||||
|
||||
def set_format(self, format):
|
||||
"""
|
||||
Set value to string format.
|
||||
@ -143,10 +144,11 @@ class Index(object):
|
||||
:param format: (*string*) Format string.
|
||||
"""
|
||||
self._index.setFormat(format)
|
||||
|
||||
|
||||
|
||||
############################################
|
||||
class DateTimeIndex(Index):
|
||||
|
||||
|
||||
def __init__(self, data=None, name='Index', start=None, end=None, periods=None, freq='D', index=None):
|
||||
if index is None:
|
||||
if not data is None:
|
||||
@ -169,7 +171,7 @@ class DateTimeIndex(Index):
|
||||
self._index = index
|
||||
self.data = miutil.pydate(list(self._index.getData()))
|
||||
self._index.setName(name)
|
||||
|
||||
|
||||
def index(self, v):
|
||||
"""
|
||||
Get index of a value.
|
||||
@ -183,7 +185,7 @@ class DateTimeIndex(Index):
|
||||
else:
|
||||
v = miutil.str2jdate(v)
|
||||
return self._index.indexOf(v)
|
||||
|
||||
|
||||
def get_loc(self, key, outkeys=False):
|
||||
"""
|
||||
Get integer location, slice or boolean mask for requested label.
|
||||
@ -201,11 +203,11 @@ class DateTimeIndex(Index):
|
||||
elif isinstance(key, (list, tuple, np.NDArray)) and isinstance(key[0], datetime.datetime):
|
||||
key = miutil.jdatetime(key)
|
||||
r = self._index.getIndices(key)
|
||||
if outkeys:
|
||||
if outkeys:
|
||||
return list(r[0]), list(r[1])
|
||||
else:
|
||||
return list(r[0])
|
||||
|
||||
|
||||
@property
|
||||
def year(self):
|
||||
"""
|
||||
@ -213,7 +215,7 @@ class DateTimeIndex(Index):
|
||||
"""
|
||||
r = self._index.getYear()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
@property
|
||||
def month(self):
|
||||
"""
|
||||
@ -221,7 +223,7 @@ class DateTimeIndex(Index):
|
||||
"""
|
||||
r = self._index.getMonth()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
@property
|
||||
def day(self):
|
||||
"""
|
||||
@ -229,7 +231,7 @@ class DateTimeIndex(Index):
|
||||
"""
|
||||
r = self._index.getDay()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
@property
|
||||
def hour(self):
|
||||
"""
|
||||
@ -237,7 +239,7 @@ class DateTimeIndex(Index):
|
||||
"""
|
||||
r = self._index.getHour()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
@property
|
||||
def minute(self):
|
||||
"""
|
||||
@ -245,7 +247,7 @@ class DateTimeIndex(Index):
|
||||
"""
|
||||
r = self._index.getMinute()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
@property
|
||||
def second(self):
|
||||
"""
|
||||
@ -254,7 +256,7 @@ class DateTimeIndex(Index):
|
||||
r = self._index.getSecond()
|
||||
return Index(index=r)
|
||||
|
||||
|
||||
|
||||
#############################################
|
||||
def date_range(start=None, end=None, periods=None, freq='D'):
|
||||
"""
|
||||
@ -269,4 +271,3 @@ def date_range(start=None, end=None, periods=None, freq='D'):
|
||||
"""
|
||||
r = DateTimeIndex(start=start, end=end, periods=periods, freq=freq)
|
||||
return r
|
||||
|
||||
Binary file not shown.
@ -1599,16 +1599,16 @@ class EarthAxes3D(Axes3DGL):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['aspect'] = 'equal'
|
||||
if not kwargs.has_key('bgcolor'):
|
||||
if 'bgcolor' not in kwargs.keys():
|
||||
kwargs['bgcolor'] = 'k'
|
||||
kwargs['clip_plane'] = False
|
||||
kwargs['axis'] = False
|
||||
if not kwargs.has_key('distance'):
|
||||
if 'distance' not in kwargs.keys():
|
||||
kwargs['distance'] = 500
|
||||
super(EarthAxes3D, self).__init__(*args, **kwargs)
|
||||
|
||||
image = kwargs.pop('image', 'world_topo.jpg')
|
||||
if not image is None:
|
||||
if image is not None:
|
||||
if not os.path.exists(image):
|
||||
image = os.path.join(migl.get_map_folder(), image)
|
||||
if os.path.exists(image):
|
||||
@ -1650,7 +1650,7 @@ class EarthAxes3D(Axes3DGL):
|
||||
|
||||
:return: Longitude and latitude lines.
|
||||
"""
|
||||
nlon = (int)(360. / lon_delta)
|
||||
nlon = int(360. / lon_delta)
|
||||
lons = np.zeros([nlon, npoints])
|
||||
lats = np.zeros([nlon, npoints])
|
||||
alts = np.zeros([nlon, npoints]) + offset
|
||||
@ -1662,7 +1662,7 @@ class EarthAxes3D(Axes3DGL):
|
||||
idx += 1
|
||||
self.plot(lons, lats, alts, **kwargs)
|
||||
|
||||
nlat = (int)(180. / lat_delta)
|
||||
nlat = int(180. / lat_delta)
|
||||
lons = np.zeros([nlat, npoints])
|
||||
lats = np.zeros([nlat, npoints])
|
||||
alts = np.zeros([nlat, npoints]) + offset
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user