mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-22 08:26:26 +01:00
opengl experiments
This commit is contained in:
parent
df4ae0dbbb
commit
8aa85d9219
1 changed files with 138 additions and 159 deletions
279
src/cad/Cad.java
279
src/cad/Cad.java
|
|
@ -1,13 +1,23 @@
|
|||
package cad;
|
||||
|
||||
import cad.fx.Plane;
|
||||
import cad.fx.Utils3D;
|
||||
import cad.math.Vector;
|
||||
import com.jogamp.newt.opengl.GLWindow;
|
||||
import com.jogamp.opengl.util.gl2.GLUT;
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
import javax.media.opengl.GL2;
|
||||
import javax.media.opengl.GLAutoDrawable;
|
||||
import javax.media.opengl.GLCapabilities;
|
||||
import javax.media.opengl.GLEventListener;
|
||||
import javax.media.opengl.GLProfile;
|
||||
import javax.media.opengl.Threading;
|
||||
import javax.media.opengl.glu.GLU;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
|
@ -19,12 +29,17 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
GLProfile.initSingleton(); // The method allows JOGL to prepare some Linux-specific locking optimizations
|
||||
}
|
||||
|
||||
public static List<Plane> initObjects = Utils3D.createCube(1);
|
||||
|
||||
static TIntObjectMap<Plane> scene = new TIntObjectHashMap<>();
|
||||
|
||||
private static GLWindow window;
|
||||
|
||||
ExecutorService updater = Executors.newSingleThreadExecutor();
|
||||
|
||||
public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException {
|
||||
|
||||
|
||||
// Get the default OpenGL profile, reflecting the best for your running platform
|
||||
GLProfile glp = GLProfile.getDefault();
|
||||
// Specifies a set of OpenGL capabilities, based on your profile.
|
||||
|
|
@ -50,6 +65,7 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
// }
|
||||
// });
|
||||
|
||||
|
||||
window.addGLEventListener(new Cad());
|
||||
|
||||
window.setSize(640, 480);
|
||||
|
|
@ -71,9 +87,13 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
// animator.start();
|
||||
}
|
||||
|
||||
float red[] = {0.8f, 0.1f, 0.0f, 1.0f};
|
||||
float green[] = {0.0f, 0.8f, 0.2f, 1.0f};
|
||||
float blue[] = {0.2f, 0.2f, 1.0f, 1.0f};
|
||||
float white[] = {1.0f, 1.0f, 1.0f};
|
||||
|
||||
|
||||
private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
|
||||
private int gear1;
|
||||
private float angle = 0.0f;
|
||||
|
||||
private int prevMouseX, prevMouseY;
|
||||
private boolean mouseRButtonDown = false;
|
||||
|
|
@ -88,46 +108,88 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
|
||||
System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
|
||||
|
||||
gl.setSwapInterval(1);
|
||||
gl.setSwapInterval(0);
|
||||
|
||||
float pos[] = {5.0f, 5.0f, 10.0f, 0.0f};
|
||||
float red[] = {0.8f, 0.1f, 0.0f, 1.0f};
|
||||
float green[] = {0.0f, 0.8f, 0.2f, 1.0f};
|
||||
float blue[] = {0.2f, 0.2f, 1.0f, 1.0f};
|
||||
float pos0[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, pos0, 0);
|
||||
|
||||
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, pos, 0);
|
||||
gl.glEnable(GL2.GL_CULL_FACE);
|
||||
gl.glEnable(GL2.GL_DEPTH_TEST);
|
||||
gl.glEnable(GL2.GL_LIGHTING);
|
||||
gl.glEnable(GL2.GL_LIGHT0);
|
||||
gl.glEnable(GL2.GL_DEPTH_TEST);
|
||||
|
||||
/* make the gears */
|
||||
gear1 = gl.glGenLists(1);
|
||||
gl.glNewList(gear1, GL2.GL_COMPILE);
|
||||
gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT_AND_DIFFUSE, red, 0);
|
||||
gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f);
|
||||
gl.glEndList();
|
||||
initNodes(gl);
|
||||
|
||||
gl.glEnable(GL2.GL_NORMALIZE);
|
||||
|
||||
|
||||
|
||||
if (drawable instanceof GLWindow) {
|
||||
GLWindow awtDrawable = (GLWindow) drawable;
|
||||
awtDrawable.addMouseListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void initNodes(GL2 gl) {
|
||||
for (Plane plane : initObjects) {
|
||||
int id = gl.glGenLists(1);
|
||||
scene.put(id, plane);
|
||||
gl.glNewList(id, GL2.GL_COMPILE);
|
||||
|
||||
//http://devernay.free.fr/cours/opengl/materials.html
|
||||
// float[] amb = {0f, 0f, 0f, 0f};
|
||||
// gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT, amb, 0);
|
||||
|
||||
float[] diff = {0.6901961f, 0.76862746f, 0.87058824f};
|
||||
gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, diff, 0);
|
||||
|
||||
// float[] spec = {0f, 0f, 0f};
|
||||
// gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, spec, 0);
|
||||
// float shine = 0.6f;
|
||||
// gl.glMaterialf(GL2.GL_FRONT, GL2.GL_SHININESS, shine * 128.0f);
|
||||
// gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT_AND_DIFFUSE, blue, 0);
|
||||
|
||||
gl.glShadeModel(GL2.GL_SMOOTH);
|
||||
|
||||
gl.glEnable(GL2.GL_LIGHTING);
|
||||
|
||||
gl.glBegin(GL2.GL_TRIANGLES);
|
||||
gl.glNormal3d(plane.normal.x, plane.normal.y, plane.normal.z); //very important!!
|
||||
for (Vector[] tr : plane.getTriangles()) {
|
||||
gl.glVertex3d(tr[0].x, tr[0].y, tr[0].z);
|
||||
gl.glVertex3d(tr[1].x, tr[1].y, tr[1].z);
|
||||
gl.glVertex3d(tr[2].x, tr[2].y, tr[2].z);
|
||||
}
|
||||
gl.glEnd();
|
||||
|
||||
gl.glEndList();
|
||||
}
|
||||
for (Plane plane : initObjects) {
|
||||
int id = gl.glGenLists(1);
|
||||
scene.put(id, plane);
|
||||
gl.glNewList(id, GL2.GL_COMPILE);
|
||||
gl.glShadeModel(GL2.GL_FLAT);
|
||||
gl.glLineWidth(1.5f);
|
||||
gl.glColor3f(255.0f, 255.0f, 255.0f);
|
||||
gl.glDisable(GL2.GL_LIGHTING);
|
||||
|
||||
gl.glNormal3d(plane.normal.x, plane.normal.y, plane.normal.z);
|
||||
for (int i = 0; i < plane.shell.size(); i++) {
|
||||
gl.glBegin(GL2.GL_LINES);
|
||||
Vector a = Plane.get(plane.shell, i);
|
||||
Vector b = Plane.get(plane.shell, i + 1);
|
||||
gl.glVertex3d(a.x, a.y, a.z);
|
||||
gl.glVertex3d(b.x, b.y, b.z);
|
||||
gl.glEnd();
|
||||
}
|
||||
gl.glEndList();
|
||||
}
|
||||
}
|
||||
|
||||
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
|
||||
GL2 gl = drawable.getGL().getGL2();
|
||||
|
||||
float h = (float) height / (float) width;
|
||||
|
||||
gl.glMatrixMode(GL2.GL_PROJECTION);
|
||||
|
||||
System.err.println("GL_VENDOR: " + gl.glGetString(GL2.GL_VENDOR));
|
||||
System.err.println("GL_RENDERER: " + gl.glGetString(GL2.GL_RENDERER));
|
||||
System.err.println("GL_VERSION: " + gl.glGetString(GL2.GL_VERSION));
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f);
|
||||
gl.glMatrixMode(GL2.GL_MODELVIEW);
|
||||
|
|
@ -140,149 +202,60 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
}
|
||||
|
||||
public void display(GLAutoDrawable drawable) {
|
||||
// Turn the gears' teeth
|
||||
// angle += 2.0f;
|
||||
|
||||
// Get the GL corresponding to the drawable we are animating
|
||||
GL2 gl = drawable.getGL().getGL2();
|
||||
|
||||
// Special handling for the case where the GLJPanel is translucent
|
||||
// and wants to be composited with other Java 2D content
|
||||
gl.glClearColor(0.5019608f, 0.5019608f, 0.5019608f, 0f);
|
||||
|
||||
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Rotate the entire assembly of gears based on how the user
|
||||
// dragged the mouse around
|
||||
gl.glPushMatrix();
|
||||
gl.glScalef(scale, scale, scale);
|
||||
|
||||
gl.glPushMatrix();
|
||||
|
||||
gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
|
||||
gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
|
||||
gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
// Place the first gear and call its display list
|
||||
gl.glPushMatrix();
|
||||
gl.glTranslatef(1.0f, 1.0f, 0.0f);
|
||||
gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
|
||||
gl.glCallList(gear1);
|
||||
for (int id : scene.keys()) {
|
||||
gl.glCallList(id);
|
||||
}
|
||||
|
||||
//
|
||||
// gl.glPushMatrix();
|
||||
// gl.glScalef(3,3,3);
|
||||
// gl.glBegin(GL2.GL_QUADS);
|
||||
// gl.glNormal3f( 0.0F, 0.0F, 1.0F);
|
||||
// gl.glVertex3f( 0.5F, 0.5F, 0.5F); gl.glVertex3f(-0.5F, 0.5F, 0.5F);
|
||||
// gl.glVertex3f(-0.5F,-0.5F, 0.5F); gl.glVertex3f( 0.5F,-0.5F, 0.5F);
|
||||
//
|
||||
// gl.glNormal3f( 0.0F, 0.0F,-1.0F);
|
||||
// gl.glVertex3f(-0.5F,-0.5F,-0.5F); gl.glVertex3f(-0.5F, 0.5F,-0.5F);
|
||||
// gl.glVertex3f( 0.5F, 0.5F,-0.5F); gl.glVertex3f( 0.5F,-0.5F,-0.5F);
|
||||
//
|
||||
// gl.glNormal3f( 0.0F, 1.0F, 0.0F);
|
||||
// gl.glVertex3f( 0.5F, 0.5F, 0.5F); gl.glVertex3f( 0.5F, 0.5F,-0.5F);
|
||||
// gl.glVertex3f(-0.5F, 0.5F,-0.5F); gl.glVertex3f(-0.5F, 0.5F, 0.5F);
|
||||
//
|
||||
// gl.glNormal3f( 0.0F,-1.0F, 0.0F);
|
||||
// gl.glVertex3f(-0.5F,-0.5F,-0.5F); gl.glVertex3f( 0.5F,-0.5F,-0.5F);
|
||||
// gl.glVertex3f( 0.5F,-0.5F, 0.5F); gl.glVertex3f(-0.5F,-0.5F, 0.5F);
|
||||
//
|
||||
// gl.glNormal3f( 1.0F, 0.0F, 0.0F);
|
||||
// gl.glVertex3f( 0.5F, 0.5F, 0.5F); gl.glVertex3f( 0.5F,-0.5F, 0.5F);
|
||||
// gl.glVertex3f( 0.5F,-0.5F,-0.5F); gl.glVertex3f( 0.5F, 0.5F,-0.5F);
|
||||
//
|
||||
// gl.glNormal3f(-1.0F, 0.0F, 0.0F);
|
||||
// gl.glVertex3f(-0.5F,-0.5F,-0.5F); gl.glVertex3f(-0.5F,-0.5F, 0.5F);
|
||||
// gl.glVertex3f(-0.5F, 0.5F, 0.5F); gl.glVertex3f(-0.5F, 0.5F,-0.5F);
|
||||
// gl.glEnd();
|
||||
// gl.glPopMatrix();
|
||||
|
||||
|
||||
gl.glPopMatrix();
|
||||
|
||||
|
||||
// Remember that every push needs a pop; this one is paired with
|
||||
// rotating the entire gear assembly
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
|
||||
}
|
||||
|
||||
public static void gear(GL2 gl,
|
||||
float inner_radius,
|
||||
float outer_radius,
|
||||
float width,
|
||||
int teeth,
|
||||
float tooth_depth) {
|
||||
int i;
|
||||
float r0, r1, r2;
|
||||
float angle, da;
|
||||
float u, v, len;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.0f;
|
||||
r2 = outer_radius + tooth_depth / 2.0f;
|
||||
|
||||
da = 2.0f * (float) Math.PI / teeth / 4.0f;
|
||||
|
||||
gl.glShadeModel(GL2.GL_FLAT);
|
||||
|
||||
gl.glNormal3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
/* draw front face */
|
||||
gl.glBegin(GL2.GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
|
||||
if (i < teeth) {
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3.0f * da), r1 * (float) Math.sin(angle + 3.0f * da), width * 0.5f);
|
||||
}
|
||||
}
|
||||
gl.glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
gl.glBegin(GL2.GL_QUADS);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + 2.0f * da), r2 * (float) Math.sin(angle + 2.0f * da), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3.0f * da), r1 * (float) Math.sin(angle + 3.0f * da), width * 0.5f);
|
||||
}
|
||||
gl.glEnd();
|
||||
|
||||
/* draw back face */
|
||||
gl.glBegin(GL2.GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
|
||||
}
|
||||
gl.glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
gl.glBegin(GL2.GL_QUADS);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), -width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), -width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
|
||||
}
|
||||
gl.glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
gl.glBegin(GL2.GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle), r1 * (float) Math.sin(angle), -width * 0.5f);
|
||||
u = r2 * (float) Math.cos(angle + da) - r1 * (float) Math.cos(angle);
|
||||
v = r2 * (float) Math.sin(angle + da) - r1 * (float) Math.sin(angle);
|
||||
len = (float) Math.sqrt(u * u + v * v);
|
||||
u /= len;
|
||||
v /= len;
|
||||
gl.glNormal3f(v, -u, 0.0f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + da), r2 * (float) Math.sin(angle + da), -width * 0.5f);
|
||||
gl.glNormal3f((float) Math.cos(angle), (float) Math.sin(angle), 0.0f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), width * 0.5f);
|
||||
gl.glVertex3f(r2 * (float) Math.cos(angle + 2 * da), r2 * (float) Math.sin(angle + 2 * da), -width * 0.5f);
|
||||
u = r1 * (float) Math.cos(angle + 3 * da) - r2 * (float) Math.cos(angle + 2 * da);
|
||||
v = r1 * (float) Math.sin(angle + 3 * da) - r2 * (float) Math.sin(angle + 2 * da);
|
||||
gl.glNormal3f(v, -u, 0.0f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(angle + 3 * da), r1 * (float) Math.sin(angle + 3 * da), -width * 0.5f);
|
||||
gl.glNormal3f((float) Math.cos(angle), (float) Math.sin(angle), 0.0f);
|
||||
}
|
||||
gl.glVertex3f(r1 * (float) Math.cos(0), r1 * (float) Math.sin(0), width * 0.5f);
|
||||
gl.glVertex3f(r1 * (float) Math.cos(0), r1 * (float) Math.sin(0), -width * 0.5f);
|
||||
gl.glEnd();
|
||||
|
||||
gl.glShadeModel(GL2.GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
gl.glBegin(GL2.GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0f * (float) Math.PI / teeth;
|
||||
gl.glNormal3f(-(float) Math.cos(angle), -(float) Math.sin(angle), 0.0f);
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), -width * 0.5f);
|
||||
gl.glVertex3f(r0 * (float) Math.cos(angle), r0 * (float) Math.sin(angle), width * 0.5f);
|
||||
}
|
||||
gl.glEnd();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseClicked(com.jogamp.newt.event.MouseEvent e) {
|
||||
}
|
||||
|
|
@ -369,7 +342,13 @@ public class Cad implements GLEventListener, com.jogamp.newt.event.MouseListener
|
|||
// });
|
||||
}
|
||||
|
||||
final double SCALE_DELTA = 1.1;
|
||||
float scale = 1;
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(com.jogamp.newt.event.MouseEvent e) {
|
||||
double scaleFactor = e.getRotation()[1] > 0 ? SCALE_DELTA : 1 / SCALE_DELTA;
|
||||
scale *= scaleFactor;
|
||||
update(window::display);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue