aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
blob: 8d67650362957b6c60353f29d440bec7f61729fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/**
 * Copyright 2010 JogAmp Community. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice, this list of
 *       conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
 *       of conditions and the following disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those of the
 * authors and should not be interpreted as representing official policies, either expressed
 * or implied, of JogAmp Community.
 */

package com.jogamp.opengl;

import com.jogamp.common.GlueGenVersion;
import javax.media.opengl.*;

import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.JogampVersion;

import java.util.List;
import java.util.jar.Manifest;
import javax.media.nativewindow.AbstractGraphicsDevice;

public class JoglVersion extends JogampVersion {

    protected static volatile JoglVersion jogampCommonVersionInfo;

    protected JoglVersion(final String packageName, final Manifest mf) {
        super(packageName, mf);
    }

    public static JoglVersion getInstance() {
        if(null == jogampCommonVersionInfo) { // volatile: ok
            synchronized(JoglVersion.class) {
                if( null == jogampCommonVersionInfo ) {
                    final String packageName = "javax.media.opengl";
                    final Manifest mf = VersionUtil.getManifest(JoglVersion.class.getClassLoader(), packageName);
                    jogampCommonVersionInfo = new JoglVersion(packageName, mf);
                }
            }
        }
        return jogampCommonVersionInfo;
    }

    public StringBuilder toString(final GL gl, StringBuilder sb) {
        sb = super.toString(sb).append(Platform.getNewline());
        getGLInfo(gl, sb);
        return sb;
    }

    public String toString(final GL gl) {
        return toString(gl, null).toString();
    }

    public static StringBuilder getAvailableCapabilitiesInfo(final GLDrawableFactory factory, final AbstractGraphicsDevice device, StringBuilder sb) {
        if(null==sb) {
            sb = new StringBuilder();
        }
        boolean done = false;
        if(null!=factory) {
            try {
                final List<GLCapabilitiesImmutable> availCaps = factory.getAvailableCapabilities(device);
                if(null != availCaps && availCaps.size()>0) {
                    for(int i=0; i<availCaps.size(); i++) {
                        sb.append("\t").append(availCaps.get(i)).append(Platform.getNewline());
                    }
                    done = true;
                }
            } catch (final GLException gle) { /* n/a */ }
        }
        if(!done) {
            sb.append("\tnone").append(Platform.getNewline());
        }
        sb.append(Platform.getNewline());
        return sb;
    }

    public static StringBuilder getAllAvailableCapabilitiesInfo(AbstractGraphicsDevice device, StringBuilder sb) {
        if(null==sb) {
            sb = new StringBuilder();
        }
        if(null == device) {
            device = GLProfile.getDefaultDevice();
        }
        sb.append(Platform.getNewline()).append(Platform.getNewline());
        sb.append("Desktop Capabilities: ").append(Platform.getNewline());
        getAvailableCapabilitiesInfo(GLDrawableFactory.getDesktopFactory(), device, sb);
        sb.append("EGL Capabilities: ").append(Platform.getNewline());
        getAvailableCapabilitiesInfo(GLDrawableFactory.getEGLFactory(), device, sb);
        return sb;
    }

    public static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, final boolean withCapabilitiesInfo) {
        if(null==sb) {
            sb = new StringBuilder();
        }
        if(null == device) {
            device = GLProfile.getDefaultDevice();
        }
        sb.append("GLProfiles on device ").append(device).append(Platform.getNewline());
        if(null!=device) {
            GLProfile.glAvailabilityToString(device, sb, "\t", 1);
        } else {
            sb.append("none");
        }
        if(withCapabilitiesInfo) {
            sb = getAllAvailableCapabilitiesInfo(device, sb);
        }
        return sb;
    }

    public static StringBuilder getGLInfo(final GL gl, final StringBuilder sb) {
        return getGLInfo(gl, sb, false);
    }
    public static StringBuilder getGLInfo(final GL gl, StringBuilder sb, final boolean withCapabilitiesAndExtensionInfo) {
        final AbstractGraphicsDevice device = gl.getContext().getGLDrawable().getNativeSurface()
                                            .getGraphicsConfiguration().getScreen().getDevice();
        if(null==sb) {
            sb = new StringBuilder();
        }

        sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
        sb.append(device.getClass().getSimpleName()).append("[type ")
                .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
        GLProfile.glAvailabilityToString(device, sb, "\t", 1);
        sb.append(Platform.getNewline());

        sb = getGLStrings(gl, sb, withCapabilitiesAndExtensionInfo);

        if( withCapabilitiesAndExtensionInfo ) {
            sb = getAllAvailableCapabilitiesInfo(device, sb);
        }
        return sb;
    }

    public static StringBuilder getGLStrings(final GL gl, final StringBuilder sb) {
        return getGLStrings(gl, sb, true);
    }

    public static StringBuilder getGLStrings(final GL gl, StringBuilder sb, final boolean withExtensions) {
        if(null==sb) {
            sb = new StringBuilder();
        }
        final GLContext ctx = gl.getContext();
        sb.append("Swap Interval  ").append(gl.getSwapInterval());
        sb.append(Platform.getNewline());
        sb.append("GL Profile     ").append(gl.getGLProfile());
        sb.append(Platform.getNewline());
        sb.append("GL Version     ").append(ctx.getGLVersion()).append(" [GL ").append(ctx.getGLVersionNumber()).append(", vendor ").append(ctx.getGLVendorVersionNumber()).append("]");
        sb.append(Platform.getNewline());
        sb.append("Quirks         ").append(ctx.getRendererQuirks());
        sb.append(Platform.getNewline());
        sb.append("Impl. class    ").append(gl.getClass().getCanonicalName());
        sb.append(Platform.getNewline());
        sb.append("GL_VENDOR      ").append(gl.glGetString(GL.GL_VENDOR));
        sb.append(Platform.getNewline());
        sb.append("GL_RENDERER    ").append(gl.glGetString(GL.GL_RENDERER));
        sb.append(Platform.getNewline());
        sb.append("GL_VERSION     ").append(gl.glGetString(GL.GL_VERSION));
        sb.append(Platform.getNewline());
        sb.append("GLSL           ").append(gl.hasGLSL()).append(", has-compiler-func: ").append(gl.isFunctionAvailable("glCompileShader"));
        if(gl.hasGLSL()) {
            sb.append(", version: ").append(gl.glGetString(GL2ES2.GL_SHADING_LANGUAGE_VERSION)).append(" / ").append(ctx.getGLSLVersionNumber());
        }
        sb.append(Platform.getNewline());
        sb.append("GL FBO: basic ").append(gl.hasBasicFBOSupport()).append(", full ").append(gl.hasFullFBOSupport());
        sb.append(Platform.getNewline());
        sb.append("GL_EXTENSIONS  ").append(ctx.getGLExtensionCount());
        sb.append(Platform.getNewline());
        if( withExtensions ) {
            sb.append("               ").append(ctx.getGLExtensionsString());
            sb.append(Platform.getNewline());
        }
        sb.append("GLX_EXTENSIONS ").append(ctx.getPlatformExtensionCount());
        sb.append(Platform.getNewline());
        if( withExtensions ) {
            sb.append("               ").append(ctx.getPlatformExtensionsString());
            sb.append(Platform.getNewline());
        }
        sb.append(VersionUtil.SEPERATOR);

        return sb;
    }

    public StringBuilder getBriefOSGLBuildInfo(final GL gl, StringBuilder sb) {
        if(null==sb) {
            sb = new StringBuilder();
        }
        sb.append("OS: ").append(Platform.getOSName()).append(", version ").append(Platform.getOSVersion()).append(", arch ").append(Platform.getArchName());
        sb.append(Platform.getNewline());
        sb.append("GL_VENDOR     ").append(gl.glGetString(GL.GL_VENDOR));
        sb.append(Platform.getNewline());
        sb.append("GL_RENDERER   ").append(gl.glGetString(GL.GL_RENDERER));
        sb.append(Platform.getNewline());
        sb.append("GL_VERSION    ").append(gl.glGetString(GL.GL_VERSION));
        sb.append(Platform.getNewline());
        sb.append("JOGL GIT sha1 ").append(getImplementationCommit());
        sb.append(Platform.getNewline());
        return sb;
    }

    public static void main(final String args[]) {
        System.err.println(VersionUtil.getPlatformInfo());
        System.err.println(GlueGenVersion.getInstance());
        // System.err.println(NativeWindowVersion.getInstance());
        System.err.println(JoglVersion.getInstance());
    }
}

m">4]; private final double[] out = new double[4]; private final double[] forward = new double[3]; private final double[] side = new double[3]; private final double[] up = new double[3]; // Buffer-based implementation private DoubleBuffer locbuf; private final DoubleBuffer matrixBuf; private final DoubleBuffer tempMatrixBuf; private final DoubleBuffer inBuf; private final DoubleBuffer outBuf; private final DoubleBuffer forwardBuf; private final DoubleBuffer sideBuf; private final DoubleBuffer upBuf; public ProjectDouble() { // Use direct buffers to avoid loading indirect buffer // implementations for applications trying to avoid doing so. // Slice up one big buffer because some NIO implementations // allocate a huge amount of memory to back even the smallest of // buffers. DoubleBuffer locbuf = Buffers.newDirectDoubleBuffer(128); int pos = 0; int sz = 16; matrixBuf = slice(locbuf, pos, sz); pos += sz; tempMatrixBuf = slice(locbuf, pos, sz); pos += sz; sz = 4; inBuf = slice(locbuf, pos, sz); pos += sz; outBuf = slice(locbuf, pos, sz); pos += sz; sz = 3; forwardBuf = slice(locbuf, pos, sz); pos += sz; sideBuf = slice(locbuf, pos, sz); pos += sz; upBuf = slice(locbuf, pos, sz); } public void destroy() { if(locbuf!=null) { locbuf.clear(); locbuf=null; } } private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) { buf.position(pos); buf.limit(pos + len); return buf.slice(); } /** * Make matrix an identity matrix */ private void __gluMakeIdentityd(DoubleBuffer m) { int oldPos = m.position(); m.put(IDENTITY_MATRIX); m.position(oldPos); } /** * Make matrix an identity matrix */ private void __gluMakeIdentityd(double[] m) { for (int i = 0; i < 16; i++) { m[i] = IDENTITY_MATRIX[i]; } } /** * Method __gluMultMatrixVecd * * @param matrix * @param in * @param out */ private void __gluMultMatrixVecd(double[] matrix, int matrix_offset, double[] in, double[] out) { for (int i = 0; i < 4; i++) { out[i] = in[0] * matrix[0*4+i+matrix_offset] + in[1] * matrix[1*4+i+matrix_offset] + in[2] * matrix[2*4+i+matrix_offset] + in[3] * matrix[3*4+i+matrix_offset]; } } /** * Method __gluMultMatrixVecd * * @param matrix * @param in * @param out */ private void __gluMultMatrixVecd(DoubleBuffer matrix, DoubleBuffer in, DoubleBuffer out) { int inPos = in.position(); int outPos = out.position(); int matrixPos = matrix.position(); for (int i = 0; i < 4; i++) { out.put(i + outPos, in.get(0+inPos) * matrix.get(0*4+i+matrixPos) + in.get(1+inPos) * matrix.get(1*4+i+matrixPos) + in.get(2+inPos) * matrix.get(2*4+i+matrixPos) + in.get(3+inPos) * matrix.get(3*4+i+matrixPos)); } } /** * @param src * @param inverse * * @return */ private boolean __gluInvertMatrixd(double[] src, double[] inverse) { int i, j, k, swap; double t; double[][] temp = tempMatrix; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { temp[i][j] = src[i*4+j]; } } __gluMakeIdentityd(inverse); for (i = 0; i < 4; i++) { // // Look for largest element in column // swap = i; for (j = i + 1; j < 4; j++) { if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) { swap = j; } } if (swap != i) { // // Swap rows. // for (k = 0; k < 4; k++) { t = temp[i][k]; temp[i][k] = temp[swap][k]; temp[swap][k] = t; t = inverse[i*4+k]; inverse[i*4+k] = inverse[swap*4+k]; inverse[swap*4+k] = t; } } if (temp[i][i] == 0) { // // No non-zero pivot. The matrix is singular, which shouldn't // happen. This means the user gave us a bad matrix. // return false; } t = temp[i][i]; for (k = 0; k < 4; k++) { temp[i][k] /= t; inverse[i*4+k] /= t; } for (j = 0; j < 4; j++) { if (j != i) { t = temp[j][i]; for (k = 0; k < 4; k++) { temp[j][k] -= temp[i][k] * t; inverse[j*4+k] -= inverse[i*4+k]*t; } } } } return true; } /** * @param src * @param inverse * * @return */ private boolean __gluInvertMatrixd(DoubleBuffer src, DoubleBuffer inverse) { int i, j, k, swap; double t; int srcPos = src.position(); int invPos = inverse.position(); DoubleBuffer temp = tempMatrixBuf; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { temp.put(i*4+j, src.get(i*4+j + srcPos)); } } __gluMakeIdentityd(inverse); for (i = 0; i < 4; i++) { // // Look for largest element in column // swap = i; for (j = i + 1; j < 4; j++) { if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) { swap = j; } } if (swap != i) { // // Swap rows. // for (k = 0; k < 4; k++) { t = temp.get(i*4+k); temp.put(i*4+k, temp.get(swap*4+k)); temp.put(swap*4+k, t); t = inverse.get(i*4+k + invPos); inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos)); inverse.put(swap*4+k + invPos, t); } } if (temp.get(i*4+i) == 0) { // // No non-zero pivot. The matrix is singular, which shouldn't // happen. This means the user gave us a bad matrix. // return false; } t = temp.get(i*4+i); for (k = 0; k < 4; k++) { temp.put(i*4+k, temp.get(i*4+k) / t); inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t); } for (j = 0; j < 4; j++) { if (j != i) { t = temp.get(j*4+i); for (k = 0; k < 4; k++) { temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t); inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t); } } } } return true; } /** * @param a * @param b * @param r */ private void __gluMultMatricesd(double[] a, int a_offset, double[] b, int b_offset, double[] r) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { r[i*4+j] = a[i*4+0+a_offset]*b[0*4+j+b_offset] + a[i*4+1+a_offset]*b[1*4+j+b_offset] + a[i*4+2+a_offset]*b[2*4+j+b_offset] + a[i*4+3+a_offset]*b[3*4+j+b_offset]; } } } /** * @param a * @param b * @param r */ private void __gluMultMatricesd(DoubleBuffer a, DoubleBuffer b, DoubleBuffer r) { int aPos = a.position(); int bPos = b.position(); int rPos = r.position(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { r.put(i*4+j + rPos, a.get(i*4+0+aPos)*b.get(0*4+j+bPos) + a.get(i*4+1+aPos)*b.get(1*4+j+bPos) + a.get(i*4+2+aPos)*b.get(2*4+j+bPos) + a.get(i*4+3+aPos)*b.get(3*4+j+bPos)); } } } /** * Normalize vector * * @param v */ private static void normalize(double[] v) { double r; r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); if ( r == 0.0 ) return; r = 1.0 / r; v[0] *= r; v[1] *= r; v[2] *= r; return; } /** * Normalize vector * * @param v */ private static void normalize(DoubleBuffer v) { double r; int vPos = v.position(); r = Math.sqrt(v.get(0+vPos) * v.get(0+vPos) + v.get(1+vPos) * v.get(1+vPos) + v.get(2+vPos) * v.get(2+vPos)); if ( r == 0.0 ) return; r = 1.0 / r; v.put(0+vPos, v.get(0+vPos) * r); v.put(1+vPos, v.get(1+vPos) * r); v.put(2+vPos, v.get(2+vPos) * r); return; } /** * Calculate cross-product * * @param v1 * @param v2 * @param result */ private static void cross(double[] v1, double[] v2, double[] result) { result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[1] = v1[2] * v2[0] - v1[0] * v2[2]; result[2] = v1[0] * v2[1] - v1[1] * v2[0]; } /** * Calculate cross-product * * @param v1 * @param v2 * @param result */ private static void cross(DoubleBuffer v1, DoubleBuffer v2, DoubleBuffer result) { int v1Pos = v1.position(); int v2Pos = v2.position(); int rPos = result.position(); result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos)); result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos)); result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos)); } /** * Method gluOrtho2D. * * @param left * @param right * @param bottom * @param top */ public void gluOrtho2D(GL2 gl, double left, double right, double bottom, double top) { gl.glOrtho(left, right, bottom, top, -1, 1); } /** * Method gluPerspective. * * @param fovy * @param aspect * @param zNear * @param zFar */ public void gluPerspective(GL2 gl, double fovy, double aspect, double zNear, double zFar) { double sine, cotangent, deltaZ; double radians = fovy / 2 * Math.PI / 180; deltaZ = zFar - zNear; sine = Math.sin(radians); if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { return; } cotangent = Math.cos(radians) / sine; __gluMakeIdentityd(matrixBuf); matrixBuf.put(0 * 4 + 0, cotangent / aspect); matrixBuf.put(1 * 4 + 1, cotangent); matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ); matrixBuf.put(2 * 4 + 3, -1); matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ); matrixBuf.put(3 * 4 + 3, 0); gl.glMultMatrixd(matrixBuf); } /** * Method gluLookAt * * @param eyex * @param eyey * @param eyez * @param centerx * @param centery * @param centerz * @param upx * @param upy * @param upz */ public void gluLookAt(GL2 gl, double eyex, double eyey, double eyez, double centerx, double centery, double centerz, double upx, double upy, double upz) { DoubleBuffer forward = this.forwardBuf; DoubleBuffer side = this.sideBuf; DoubleBuffer up = this.upBuf; forward.put(0, centerx - eyex); forward.put(1, centery - eyey); forward.put(2, centerz - eyez); up.put(0, upx); up.put(1, upy); up.put(2, upz); normalize(forward); /* Side = forward x up */ cross(forward, up, side); normalize(side); /* Recompute up as: up = side x forward */ cross(side, forward, up); __gluMakeIdentityd(matrixBuf); matrixBuf.put(0 * 4 + 0, side.get(0)); matrixBuf.put(1 * 4 + 0, side.get(1)); matrixBuf.put(2 * 4 + 0, side.get(2)); matrixBuf.put(0 * 4 + 1, up.get(0)); matrixBuf.put(1 * 4 + 1, up.get(1)); matrixBuf.put(2 * 4 + 1, up.get(2)); matrixBuf.put(0 * 4 + 2, -forward.get(0)); matrixBuf.put(1 * 4 + 2, -forward.get(1)); matrixBuf.put(2 * 4 + 2, -forward.get(2)); gl.glMultMatrixd(matrixBuf); gl.glTranslated(-eyex, -eyey, -eyez); } /** * Method gluProject * * @param objx * @param objy * @param objz * @param modelMatrix * @param projMatrix * @param viewport * @param win_pos * * @return */ public boolean gluProject(double objx, double objy, double objz, double[] modelMatrix, int modelMatrix_offset, double[] projMatrix, int projMatrix_offset, int[] viewport, int viewport_offset, double[] win_pos, int win_pos_offset ) { double[] in = this.in; double[] out = this.out; in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0; __gluMultMatrixVecd(modelMatrix, modelMatrix_offset, in, out); __gluMultMatrixVecd(projMatrix, projMatrix_offset, out, in); if (in[3] == 0.0) return false; in[3] = (1.0 / in[3]) * 0.5; // Map x, y and z to range 0-1 in[0] = in[0] * in[3] + 0.5f; in[1] = in[1] * in[3] + 0.5f; in[2] = in[2] * in[3] + 0.5f; // Map x,y to viewport win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset]; win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset]; win_pos[2+win_pos_offset] = in[2]; return true; } /** * Method gluProject * * @param objx * @param objy * @param objz * @param modelMatrix * @param projMatrix * @param viewport * @param win_pos * * @return */ public boolean gluProject(double objx, double objy, double objz, DoubleBuffer modelMatrix, DoubleBuffer projMatrix, IntBuffer viewport, DoubleBuffer win_pos) { DoubleBuffer in = this.inBuf; DoubleBuffer out = this.outBuf; in.put(0, objx); in.put(1, objy); in.put(2, objz); in.put(3, 1.0); __gluMultMatrixVecd(modelMatrix, in, out); __gluMultMatrixVecd(projMatrix, out, in); if (in.get(3) == 0.0) return false; in.put(3, (1.0 / in.get(3)) * 0.5); // Map x, y and z to range 0-1 in.put(0, in.get(0) * in.get(3) + 0.5f); in.put(1, in.get(1) * in.get(3) + 0.5f); in.put(2, in.get(2) * in.get(3) + 0.5f); // Map x,y to viewport int vPos = viewport.position(); int wPos = win_pos.position(); win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos)); win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos)); win_pos.put(2+wPos, in.get(2)); return true; } /** * Method gluUnproject * * @param winx * @param winy * @param winz * @param modelMatrix * @param projMatrix * @param viewport * @param obj_pos * * @return */ public boolean gluUnProject(double winx, double winy, double winz, double[] modelMatrix, int modelMatrix_offset, double[] projMatrix, int projMatrix_offset, int[] viewport, int viewport_offset, double[] obj_pos, int obj_pos_offset) { double[] in = this.in; double[] out = this.out; __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix); if (!__gluInvertMatrixd(matrix, matrix)) return false; in[0] = winx; in[1] = winy; in[2] = winz; in[3] = 1.0; // Map x and y from window coordinates in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset]; in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset]; // Map to range -1 to 1 in[0] = in[0] * 2 - 1; in[1] = in[1] * 2 - 1; in[2] = in[2] * 2 - 1; __gluMultMatrixVecd(matrix, 0, in, out); if (out[3] == 0.0) return false; out[3] = 1.0 / out[3]; obj_pos[0+obj_pos_offset] = out[0] * out[3]; obj_pos[1+obj_pos_offset] = out[1] * out[3]; obj_pos[2+obj_pos_offset] = out[2] * out[3]; return true; } /** * Method gluUnproject * * @param winx * @param winy * @param winz * @param modelMatrix * @param projMatrix * @param viewport * @param obj_pos * * @return */ public boolean gluUnProject(double winx, double winy, double winz, DoubleBuffer modelMatrix, DoubleBuffer projMatrix, IntBuffer viewport, DoubleBuffer obj_pos) { DoubleBuffer in = this.inBuf; DoubleBuffer out = this.outBuf; __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf); if (!__gluInvertMatrixd(matrixBuf, matrixBuf)) return false; in.put(0, winx); in.put(1, winy); in.put(2, winz); in.put(3, 1.0); // Map x and y from window coordinates int vPos = viewport.position(); int oPos = obj_pos.position(); in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos)); in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos)); // Map to range -1 to 1 in.put(0, in.get(0) * 2 - 1); in.put(1, in.get(1) * 2 - 1); in.put(2, in.get(2) * 2 - 1); __gluMultMatrixVecd(matrixBuf, in, out); if (out.get(3) == 0.0) return false; out.put(3, 1.0 / out.get(3)); obj_pos.put(0+oPos, out.get(0) * out.get(3)); obj_pos.put(1+oPos, out.get(1) * out.get(3)); obj_pos.put(2+oPos, out.get(2) * out.get(3)); return true; } /** * Method gluUnproject4 * * @param winx * @param winy * @param winz * @param clipw * @param modelMatrix * @param projMatrix * @param viewport * @param near * @param far * @param obj_pos * * @return */ public boolean gluUnProject4(double winx, double winy, double winz, double clipw, double[] modelMatrix, int modelMatrix_offset, double[] projMatrix, int projMatrix_offset, int[] viewport, int viewport_offset, double near, double far, double[] obj_pos, int obj_pos_offset ) { double[] in = this.in; double[] out = this.out; __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix); if (!__gluInvertMatrixd(matrix, matrix)) return false; in[0] = winx; in[1] = winy; in[2] = winz; in[3] = clipw; // Map x and y from window coordinates in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset]; in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset]; in[2] = (in[2] - near) / (far - near); // Map to range -1 to 1 in[0] = in[0] * 2 - 1; in[1] = in[1] * 2 - 1; in[2] = in[2] * 2 - 1; __gluMultMatrixVecd(matrix, 0, in, out); if (out[3] == 0.0) return false; obj_pos[0+obj_pos_offset] = out[0]; obj_pos[1+obj_pos_offset] = out[1]; obj_pos[2+obj_pos_offset] = out[2]; obj_pos[3+obj_pos_offset] = out[3]; return true; } /** * Method gluUnproject4 * * @param winx * @param winy * @param winz * @param clipw * @param modelMatrix * @param projMatrix * @param viewport * @param near * @param far * @param obj_pos * * @return */ public boolean gluUnProject4(double winx, double winy, double winz, double clipw, DoubleBuffer modelMatrix, DoubleBuffer projMatrix, IntBuffer viewport, double near, double far, DoubleBuffer obj_pos) { DoubleBuffer in = this.inBuf; DoubleBuffer out = this.outBuf; __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf); if (!__gluInvertMatrixd(matrixBuf, matrixBuf)) return false; in.put(0, winx); in.put(1, winy); in.put(2, winz); in.put(3, clipw); // Map x and y from window coordinates int vPos = viewport.position(); in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos)); in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos)); in.put(2, (in.get(2) - near) / (far - near)); // Map to range -1 to 1 in.put(0, in.get(0) * 2 - 1); in.put(1, in.get(1) * 2 - 1); in.put(2, in.get(2) * 2 - 1); __gluMultMatrixVecd(matrixBuf, in, out); if (out.get(3) == 0.0) return false; int oPos = obj_pos.position(); obj_pos.put(0+oPos, out.get(0)); obj_pos.put(1+oPos, out.get(1)); obj_pos.put(2+oPos, out.get(2)); obj_pos.put(3+oPos, out.get(3)); return true; } /** * Method gluPickMatrix * * @param x * @param y * @param deltaX * @param deltaY * @param viewport */ public void gluPickMatrix(GL2 gl, double x, double y, double deltaX, double deltaY, IntBuffer viewport) { if (deltaX <= 0 || deltaY <= 0) { return; } /* Translate and scale the picked region to the entire window */ int vPos = viewport.position(); gl.glTranslated((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX, (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY, 0); gl.glScaled(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0); } /** * Method gluPickMatrix * * @param x * @param y * @param deltaX * @param deltaY * @param viewport * @param viewport_offset */ public void gluPickMatrix(GL2 gl, double x, double y, double deltaX, double deltaY, int[] viewport, int viewport_offset) { if (deltaX <= 0 || deltaY <= 0) { return; } /* Translate and scale the picked region to the entire window */ gl.glTranslated((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX, (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY, 0); gl.glScaled(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0); } }