| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.opengl.examples; |
| |
| |
| import org.eclipse.opengl.*; |
| import org.eclipse.swt.*; |
| import org.eclipse.swt.graphics.*; |
| import org.eclipse.swt.layout.*; |
| import org.eclipse.swt.widgets.*; |
| |
| class ObjectsTab extends OpenGLTab { |
| private class Shape { |
| private String name; |
| private int index; |
| /** |
| * Constructor. |
| * |
| * @param name the display name of this shape |
| * @param index the display list index corresponding to this shape |
| */ |
| Shape(String name, int index) { |
| super(); |
| this.index = index; |
| this.name = name; |
| } |
| void dispose() { |
| GL.glDeleteLists(index, 1); |
| } |
| void draw() { |
| GL.glCallList(index); |
| } |
| String getName() { |
| return name; |
| } |
| } |
| |
| private Shape[] shapes; |
| private Shape currentShape; |
| private float xRot = 0.0f, yRot = 0.0f; |
| private boolean fill = true; |
| private int quadratic; |
| private final static int SLEEP_LENGTH = 50; |
| |
| /** |
| * @see OpenGLTab#createControls(Composite) |
| */ |
| void createControls(final Composite composite) { |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginWidth = 0; |
| Composite controls = new Composite(composite, SWT.NONE); |
| controls.setLayout(layout); |
| |
| new Label(controls, SWT.NONE).setText("Object:"); |
| final Combo objectsCombo = new Combo(controls, SWT.READ_ONLY); |
| for (int i = 0; i < shapes.length; i++) { |
| objectsCombo.add(shapes[i].getName()); |
| } |
| objectsCombo.select(0); |
| objectsCombo.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| currentShape = shapes[objectsCombo.getSelectionIndex()]; |
| } |
| }); |
| |
| final Button fillToggleButton = new Button(controls, SWT.CHECK); |
| fillToggleButton.setText("Fill"); |
| fillToggleButton.setSelection(true); |
| fillToggleButton.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event e) { |
| fill = fillToggleButton.getSelection(); |
| } |
| }); |
| |
| ColorSelectionGroup colorGroup = |
| new ColorSelectionGroup(composite, SWT.NONE); |
| colorGroup.setText("Foreground color"); |
| colorGroup.addColorSelectionListener(new IColorSelectionListener() { |
| public void handleColorSelection(RGB rgb) { |
| GL.glColor3ub((byte) rgb.red, (byte) rgb.green, (byte) rgb.blue); |
| } |
| }); |
| } |
| |
| /** |
| * @see OpenGLTab#dispose() |
| */ |
| void dispose() { |
| super.dispose(); |
| GLU.gluDeleteQuadric(quadratic); |
| for (int i = 0; i < shapes.length; i++) { |
| shapes [i].dispose(); |
| } |
| } |
| |
| /** |
| * Creates a circle centered at 0,0 in the viewport. |
| * |
| * @param radius |
| * @param xShrink |
| * @param yShrink |
| */ |
| void drawCircle(float radius, float xShrink, float yShrink) { |
| GL.glBegin(GL.GL_POLYGON); |
| float dia = (float) 2.0 * (float) Math.PI; |
| for (float angle = 0.0f; angle <= dia; angle += 0.1f) { |
| GL.glVertex2d(radius * Math.cos(angle), radius * Math.sin(angle)); |
| } |
| GL.glEnd(); |
| } |
| |
| /** |
| * Creates a cube centered at 0,0 in the viewport. |
| * |
| * @param width |
| * @param height |
| * @param depth |
| */ |
| void drawCube(float width, float height, float depth) { |
| GL.glBegin(GL.GL_QUADS); |
| // front |
| GL.glVertex3f(-width, -height, depth); // bottom left |
| GL.glVertex3f(width, -height, depth); // bottom right |
| GL.glVertex3f(width, height, depth); // top right |
| GL.glVertex3f(-width, height, depth); // top left |
| // back |
| GL.glVertex3f(-width, -height, -depth); // bottom left |
| GL.glVertex3f(width, -height, -depth); // bottom right |
| GL.glVertex3f(width, height, -depth); // top right |
| GL.glVertex3f(-width, height, -depth); // top left |
| // left |
| GL.glVertex3f(-width, -height, -depth); // bottom left |
| GL.glVertex3f(-width, -height, depth); // bottom right |
| GL.glVertex3f(-width, height, depth); // top right |
| GL.glVertex3f(-width, height, -depth); // top left |
| // right |
| GL.glVertex3f(width, -height, depth); // bottom left |
| GL.glVertex3f(width, -height, -depth); // bottom right |
| GL.glVertex3f(width, height, -depth); // top right |
| GL.glVertex3f(width, height, depth); // top left |
| // top |
| GL.glVertex3f(width, height, -depth); // back right |
| GL.glVertex3f(-width, height, -depth); // back left |
| GL.glVertex3f(-width, height, depth); // front left |
| GL.glVertex3f(width, height, depth); // front right |
| // bottom |
| GL.glVertex3f(width, -height, depth); // front right |
| GL.glVertex3f(-width, -height, depth); // front left |
| GL.glVertex3f(-width, -height, -depth); // back left |
| GL.glVertex3f(width, -height, -depth); // back right |
| GL.glEnd(); |
| } |
| |
| /** |
| * Creates a pyramid centered at 0,0 in the viewport. |
| * |
| * @param width |
| * @param height |
| * @param depth |
| */ |
| void drawPyramid(float width, float height, float depth) { |
| GL.glBegin(GL.GL_TRIANGLES); |
| // front |
| GL.glVertex3f(0.0f, height, 0.0f); // top |
| GL.glVertex3f(-width, -height, depth); // left |
| GL.glVertex3f(width, -height, depth); // right |
| // left |
| GL.glVertex3f(0.0f, height, 0.0f); // top |
| GL.glVertex3f(-width, -height, -depth); // left |
| GL.glVertex3f(-width, -height, depth); // right |
| // front |
| GL.glVertex3f(-width, -height, -depth); // left |
| GL.glVertex3f(0.0f, height, 0.0f); // top |
| GL.glVertex3f(width, -height, -depth); // right |
| // right |
| GL.glVertex3f(0.0f, height, 0.0f); // top |
| GL.glVertex3f(width, -height, depth); // left |
| GL.glVertex3f(width, -height, -depth); // right |
| GL.glEnd(); |
| GL.glBegin(GL.GL_QUADS); |
| // bottom |
| GL.glVertex3f(-width, -height, depth); // front left |
| GL.glVertex3f(-width, -height, -depth); // back left |
| GL.glVertex3f(width, -height, -depth); // back right |
| GL.glVertex3f(width, -height, depth); // front right |
| GL.glEnd(); |
| } |
| |
| /** |
| * Creates a square centered at 0,0 in the viewport. |
| * |
| * @param width |
| * @param height |
| */ |
| void drawSquare(float width, float height) { |
| GL.glBegin(GL.GL_QUADS); |
| GL.glVertex3f(-width, -height, 0.0f); // bottom left |
| GL.glVertex3f(width, -height, 0.0f); // bottom right |
| GL.glVertex3f(width, height, 0.0f); // top right |
| GL.glVertex3f(-width, height, 0.0f); // top left |
| GL.glEnd(); |
| } |
| |
| /** |
| * This method is from glut_shapes.c . |
| * |
| * @param r |
| * @param R |
| * @param nsides |
| * @param rings |
| */ |
| void drawTorus(float r, float R, int nsides, int rings) { |
| float ringDelta = 2.0f * (float) Math.PI / rings; |
| float sideDelta = 2.0f * (float) Math.PI / nsides; |
| float theta = 0.0f; |
| float cosTheta = 1.0f; |
| float sinTheta = 0.0f; |
| |
| for (int i = rings - 1; i >= 0; i--) { |
| float theta1 = theta + ringDelta; |
| float cosTheta1 = (float) Math.cos(theta1); |
| float sinTheta1 = (float) Math.sin(theta1); |
| GL.glBegin(GL.GL_QUAD_STRIP); |
| float phi = 0.0f; |
| |
| for (int j = nsides; j >= 0; j--) { |
| phi += sideDelta; |
| float cosPhi = (float) Math.cos(phi); |
| float sinPhi = (float) Math.sin(phi); |
| float dist = R + r * cosPhi; |
| GL.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); |
| GL.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); |
| GL.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); |
| GL.glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi); |
| } |
| |
| GL.glEnd(); |
| theta = theta1; |
| cosTheta = cosTheta1; |
| sinTheta = sinTheta1; |
| } |
| } |
| |
| /** |
| * Creates a triangle centered at 0,0 in the viewport. |
| * |
| * @param width |
| * @param height |
| */ |
| void drawTriangle(float width, float height) { |
| GL.glBegin(GL.GL_TRIANGLES); |
| GL.glVertex3f(0.0f, height, 0.0f); // middle |
| GL.glVertex3f(-width, -height, 0.0f); // left |
| GL.glVertex3f(width, -height, 0.0f); // right |
| GL.glEnd(); |
| } |
| |
| /** |
| * @see OpenGLTab#getSleepLength() |
| */ |
| int getSleepLength() { |
| return SLEEP_LENGTH; |
| } |
| |
| /** |
| * @see OpenGLTab#getTabText() |
| */ |
| String getTabText() { |
| return "Objects"; |
| } |
| |
| /** |
| * @see OpenGLTab#init() |
| */ |
| void init() { |
| GL.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); |
| GL.glColor3f(1.0f, 0.0f, 0.0f); |
| GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); |
| GL.glClearDepth(1.0); |
| quadratic = GLU.gluNewQuadric(); |
| GLU.gluQuadricNormals(quadratic, GLU.GLU_SMOOTH); |
| GL.glLineWidth(2); |
| |
| GL.glEnable(GL.GL_DEPTH_TEST); |
| |
| // create the display lists and shapes |
| shapes = new Shape[11]; |
| int index = 1; |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawTriangle(2.0f, 2.0f); |
| GL.glEndList(); |
| shapes[0] = new Shape("Triangle", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawPyramid(2.0f, 2.0f, 2.0f); |
| GL.glEndList(); |
| shapes[1] = new Shape("Pyramid", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawSquare(2.0f, 2.0f); |
| GL.glEndList(); |
| shapes[2] = new Shape("Square", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawCube(2.0f, 2.0f, 2.0f); |
| GL.glEndList(); |
| shapes[3] = new Shape("Cube", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawCircle(2.0f, 0.0f, 0.0f); |
| GL.glEndList(); |
| shapes[4] = new Shape("Circle", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| GLU.gluPartialDisk(quadratic, 0.5, 2.0, 18, 18, 90, 125); |
| GL.glEndList(); |
| shapes[5] = new Shape("Partial Disk", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| GLU.gluDisk(quadratic, 0.5, 2.0, 18, 18); |
| GL.glEndList(); |
| shapes[6] = new Shape("Disk", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| drawTorus(1, 2, 18, 18); |
| GL.glEndList(); |
| shapes[7] = new Shape("Torus", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| GLU.gluSphere(quadratic, 2.0, 18, 18); |
| GL.glEndList(); |
| shapes[8] = new Shape("Sphere", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| GLU.gluCylinder(quadratic, 2.0, 2.0, 4, 18, 18); |
| GL.glEndList(); |
| shapes[9] = new Shape("Cylinder", index++); |
| |
| GL.glNewList(index, GL.GL_COMPILE); |
| GLU.gluCylinder(quadratic, 0, 2.0, 4, 18, 18); |
| GL.glEndList(); |
| shapes[10] = new Shape("Cone", index++); |
| |
| currentShape = shapes[0]; |
| } |
| |
| /** |
| * @see OpenGLTab#renderScene() |
| */ |
| void renderScene() { |
| GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); |
| GL.glLoadIdentity(); |
| GL.glTranslatef(0.0f, 0.0f, -14.0f); |
| // rotate around X and Y axis |
| GL.glRotatef(yRot, 0.0f, 1.0f, 0.0f); |
| GL.glRotatef(xRot, 1.0f, 0.0f, 0.0f); |
| // sets polygon fill mode |
| if (fill) { |
| GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); |
| } else { |
| GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); |
| } |
| currentShape.draw(); |
| yRot += 1.5; |
| xRot += 1.5; |
| } |
| } |