mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
229 lines
8.4 KiB
Java
229 lines
8.4 KiB
Java
import com.jogamp.opengl.*;
|
|
import com.jogamp.opengl.awt.GLJPanel;
|
|
import com.jogamp.opengl.util.FPSAnimator;
|
|
import com.jogamp.opengl.util.GLBuffers;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector4f;
|
|
import org.meteoinfo.chart.graphic.sphere.Sphere;
|
|
import org.meteoinfo.math.Matrix4f;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.IntBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
public class SphereTest implements GLEventListener {
|
|
|
|
private List<Sphere> spheres;
|
|
private IntBuffer vbo;
|
|
private int sizePosition;
|
|
private int sizeColor;
|
|
private int sizeNormal;
|
|
private float[] vertexPosition;
|
|
private float[] vertexNormal;
|
|
private float[] vertexColor;
|
|
private int[] vertexIndices;
|
|
private float rquad = 0.0f;
|
|
|
|
public SphereTest() {
|
|
vbo = GLBuffers.newDirectIntBuffer(2);
|
|
createSpheres(3);
|
|
updateSphereVertex();
|
|
}
|
|
|
|
void createSpheres(int n) {
|
|
this.spheres = new ArrayList<>();
|
|
for (int i = 0; i < n; i++) {
|
|
this.spheres.add(new Sphere(0.1f, 36, 18));
|
|
}
|
|
}
|
|
|
|
private void updateSphereVertex() {
|
|
List<Vector3f> vertexPositionList = new ArrayList<>();
|
|
List<Vector3f> vertexNormalList = new ArrayList<>();
|
|
List<Vector4f> vertexColorList = new ArrayList<>();
|
|
List<Integer> vertexIndexList = new ArrayList<>();
|
|
Vector3f vp;
|
|
int idx = 0, sn = this.spheres.size();
|
|
float max = 0.5f;
|
|
float x, y, z;
|
|
for (Sphere sphere : this.spheres) {
|
|
z = max / sn * idx;
|
|
x = z * (float) Math.sin(z * 20);
|
|
y = z * (float) Math.sin(z * 20);
|
|
vp = new Vector3f(x, y, z);
|
|
Matrix4f matrix = new Matrix4f();
|
|
matrix.translate(vp);
|
|
List<Vector3f> vertices = sphere.getVertices();
|
|
int n = vertices.size();
|
|
int nAdded = vertexPositionList.size();
|
|
for (Vector3f v : vertices) {
|
|
vertexPositionList.add(matrix.mul(v));
|
|
}
|
|
List<Vector3f> normals = sphere.getNormals();
|
|
vertexNormalList.addAll(normals);
|
|
float[] color = Color.RED.getRGBComponents(null);
|
|
for (int j = 0; j < n; j++) {
|
|
vertexColorList.add(new Vector4f(color));
|
|
}
|
|
if (nAdded == 0) {
|
|
vertexIndexList.addAll(sphere.getIndices());
|
|
} else {
|
|
for (int ii : sphere.getIndices()) {
|
|
vertexIndexList.add(ii + nAdded);
|
|
}
|
|
}
|
|
idx += 1;
|
|
}
|
|
|
|
int n = vertexPositionList.size();
|
|
this.vertexPosition = new float[n * 3];
|
|
this.vertexNormal = new float[n * 3];
|
|
this.vertexColor = new float[n * 4];
|
|
Vector3f v;
|
|
Vector4f v4;
|
|
for (int i = 0, j = 0, k = 0; i < n; i++, j+=3, k+=4) {
|
|
v = vertexPositionList.get(i);
|
|
vertexPosition[j] = v.x;
|
|
vertexPosition[j + 1] = v.y;
|
|
vertexPosition[j + 2] = v.z;
|
|
v = vertexNormalList.get(i);
|
|
vertexNormal[j] = v.x;
|
|
vertexNormal[j + 1] = v.y;
|
|
vertexNormal[j + 2] = v.z;
|
|
v4 = vertexColorList.get(i);
|
|
vertexColor[k] = v4.x;
|
|
vertexColor[k + 1] = v4.y;
|
|
vertexColor[k + 2] = v4.z;
|
|
vertexColor[k + 3] = v4.w;
|
|
}
|
|
vertexIndices = vertexIndexList.stream().mapToInt(Integer::intValue).toArray();
|
|
}
|
|
|
|
private void updateBuffer(GL2 gl) {
|
|
FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(this.vertexPosition);
|
|
sizePosition = vertexBuffer.capacity() * Float.BYTES;
|
|
|
|
FloatBuffer colorBuffer = GLBuffers.newDirectFloatBuffer(vertexColor);
|
|
sizeColor = colorBuffer.capacity() * Float.BYTES;
|
|
|
|
FloatBuffer normalBuffer = GLBuffers.newDirectFloatBuffer(vertexNormal);
|
|
sizeNormal = normalBuffer.capacity() * Float.BYTES;
|
|
|
|
int totalSize = sizePosition + sizeColor + sizeNormal;
|
|
|
|
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, sizeColor, colorBuffer);
|
|
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizePosition + sizeColor, sizeNormal, normalBuffer);
|
|
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
|
|
|
IntBuffer indexBuffer = GLBuffers.newDirectIntBuffer(this.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);
|
|
}
|
|
|
|
@Override
|
|
public void init(GLAutoDrawable glAutoDrawable) {
|
|
GL2 gl = glAutoDrawable.getGL().getGL2();
|
|
|
|
updateBuffer(gl);
|
|
|
|
gl.glShadeModel( GL2.GL_SMOOTH );
|
|
gl.glClearColor( 0f, 0f, 0f, 0f );
|
|
gl.glClearDepth( 1.0f );
|
|
gl.glEnable( GL2.GL_DEPTH_TEST );
|
|
gl.glDepthFunc( GL2.GL_LEQUAL );
|
|
gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
|
|
gl.glEnable(GL2.GL_COLOR_MATERIAL);
|
|
|
|
gl.glEnable(GL2.GL_LIGHTING);
|
|
gl.glEnable(GL2.GL_LIGHT1);
|
|
//gl.glEnable(GL2.GL_AUTO_NORMAL);
|
|
//gl.glEnable(GLLightingFunc.GL_NORMALIZE);
|
|
|
|
gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, new float[]{0.2f, 0.2f, 0.2f, 1.f}, 0);
|
|
//gl.glLightfv(this.light, GL2.GL_AMBIENT, ambient, 0);
|
|
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_SPECULAR, new float[]{1.f, 1.f, 1.f, 1.f}, 0);
|
|
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, new float[]{1.f, 1.f, 1.f, 1.f}, 0);
|
|
gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, new float[]{0.f, 0.f, 1.f, 0.f}, 0);
|
|
|
|
//Material
|
|
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, new float[]{0.2f, 0.2f, 0.2f, 1.f}, 0);
|
|
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, new float[]{0.8f, 0.8f, 0.8f, 1.f}, 0);
|
|
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, new float[]{1.f, 1.f, 1.f, 1.f}, 0);
|
|
gl.glMaterialf(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, 50);
|
|
}
|
|
|
|
@Override
|
|
public void dispose(GLAutoDrawable glAutoDrawable) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void display(GLAutoDrawable glAutoDrawable) {
|
|
GL2 gl = glAutoDrawable.getGL().getGL2();
|
|
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
|
|
gl.glLoadIdentity();
|
|
|
|
// Rotate The Cube On X, Y & Z
|
|
gl.glRotatef(rquad, 1.0f, 1.0f, 1.0f);
|
|
|
|
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);
|
|
|
|
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo.get(1));
|
|
|
|
gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
|
|
gl.glNormalPointer(GL.GL_FLOAT, 0, sizePosition + sizeColor);
|
|
|
|
gl.glEnable(GL.GL_CULL_FACE);
|
|
gl.glDrawElements(GL2.GL_TRIANGLES, this.vertexIndices.length, GL.GL_UNSIGNED_INT, 0);
|
|
|
|
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
|
|
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
|
|
gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
|
|
|
|
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
|
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
|
|
rquad -= 0.15f;
|
|
}
|
|
|
|
@Override
|
|
public void reshape(GLAutoDrawable glAutoDrawable, int i, int i1, int i2, int i3) {
|
|
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
//getting the capabilities object of GL2 profile
|
|
final GLProfile profile = GLProfile.get(GLProfile.GL2);
|
|
GLCapabilities capabilities = new GLCapabilities(profile);
|
|
// The canvas
|
|
final GLJPanel glcanvas = new GLJPanel(capabilities);
|
|
SphereTest sphereTest = new SphereTest();
|
|
glcanvas.addGLEventListener(sphereTest);
|
|
//creating frame
|
|
final JFrame frame = new JFrame ("Sphere test");
|
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
frame.setSize(400, 400);
|
|
//adding canvas to frame
|
|
frame.getContentPane().add(glcanvas);
|
|
frame.setVisible(true);
|
|
|
|
final FPSAnimator animator = new FPSAnimator(glcanvas, 300, true);
|
|
animator.start();
|
|
}
|
|
|
|
}
|