OSDN Git Service

Merge branch 'git-svn'
[nyartoolkit-and/nyartoolkit-and.git] / trunk / src.utils / jogl / jp / nyatla / nyartoolkit / jogl / utils / NyARGLUtil.java
1 /* \r
2  * PROJECT: NyARToolkit JOGL utilities.\r
3  * --------------------------------------------------------------------------------\r
4  * This work is based on the original ARToolKit developed by\r
5  *   Hirokazu Kato\r
6  *   Mark Billinghurst\r
7  *   HITLab, University of Washington, Seattle\r
8  * http://www.hitl.washington.edu/artoolkit/\r
9  *\r
10  * The NyARToolkit is Java edition ARToolKit class library.\r
11  * Copyright (C)2008-2009 Ryo Iizuka\r
12  *\r
13  * This program is free software: you can redistribute it and/or modify\r
14  * it under the terms of the GNU General Public License as published by\r
15  * the Free Software Foundation, either version 3 of the License, or\r
16  * (at your option) any later version.\r
17  * \r
18  * This program is distributed in the hope that it will be useful,\r
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21  * GNU General Public License for more details.\r
22  *\r
23  * You should have received a copy of the GNU General Public License\r
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
25  * \r
26  * For further information please contact.\r
27  *      http://nyatla.jp/nyatoolkit/\r
28  *      <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
29  * \r
30  */\r
31 package jp.nyatla.nyartoolkit.jogl.utils;\r
32 \r
33 import java.nio.*;\r
34 import javax.media.opengl.GL;\r
35 import javax.media.opengl.glu.GLU;\r
36 \r
37 import jp.nyatla.nyartoolkit.NyARException;\r
38 import jp.nyatla.nyartoolkit.core.*;\r
39 import jp.nyatla.nyartoolkit.core.raster.rgb.*;\r
40 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
41 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
42 import jp.nyatla.nyartoolkit.core.types.*;\r
43 /**\r
44  * NyARToolkit用のJOGL支援関数群\r
45  */\r
46 public class NyARGLUtil\r
47 {\r
48         private javax.media.opengl.GL _gl;\r
49 \r
50         private javax.media.opengl.glu.GLU _glu;\r
51 \r
52         public NyARGLUtil(javax.media.opengl.GL i_gl)\r
53         {\r
54                 this._gl = i_gl;\r
55                 this._glu = new GLU();\r
56         }\r
57         /**\r
58          * ラスタのGLタイプを取得する。\r
59          * @param i_buffer_type\r
60          * @return\r
61          * @throws NyARException\r
62          */\r
63         final static private int getGlPixelFormat(int i_buffer_type) throws NyARException\r
64         {\r
65                 switch(i_buffer_type){\r
66                 case NyARBufferType.BYTE1D_B8G8R8_24:\r
67                         return GL.GL_BGR;\r
68                 case NyARBufferType.BYTE1D_R8G8B8_24:\r
69                         return GL.GL_RGB;\r
70                 default:\r
71                         throw new NyARException();\r
72                 }\r
73         }\r
74         \r
75         /**\r
76          * GLNyARRaster_RGBをバックグラウンドに書き出す。\r
77          * @param image\r
78          * @param zoom\r
79          */\r
80         public void drawBackGround(INyARRgbRaster i_raster, double i_zoom) throws NyARException\r
81         {\r
82                 IntBuffer texEnvModeSave = IntBuffer.allocate(1);\r
83                 boolean lightingSave;\r
84                 boolean depthTestSave;\r
85                 javax.media.opengl.GL gl = this._gl;\r
86                 final NyARIntSize rsize=i_raster.getSize();\r
87 \r
88                 // Prepare an orthographic projection, set camera position for 2D drawing, and save GL state.\r
89                 gl.glGetTexEnviv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave); // Save GL texture environment mode.\r
90                 if (texEnvModeSave.array()[0] != GL.GL_REPLACE) {\r
91                         gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);\r
92                 }\r
93                 lightingSave = gl.glIsEnabled(GL.GL_LIGHTING); // Save enabled state of lighting.\r
94                 if (lightingSave == true) {\r
95                         gl.glDisable(GL.GL_LIGHTING);\r
96                 }\r
97                 depthTestSave = gl.glIsEnabled(GL.GL_DEPTH_TEST); // Save enabled state of depth test.\r
98                 if (depthTestSave == true) {\r
99                         gl.glDisable(GL.GL_DEPTH_TEST);\r
100                 }\r
101                 gl.glMatrixMode(GL.GL_PROJECTION);\r
102                 gl.glPushMatrix();\r
103                 gl.glLoadIdentity();\r
104                 _glu.gluOrtho2D(0.0,rsize.w, 0.0,rsize.h);\r
105                 gl.glMatrixMode(GL.GL_MODELVIEW);\r
106                 gl.glPushMatrix();\r
107                 gl.glLoadIdentity();\r
108                 arglDispImageStateful(i_raster, i_zoom);\r
109 \r
110                 // Restore previous projection, camera position, and GL state.\r
111                 gl.glMatrixMode(GL.GL_PROJECTION);\r
112                 gl.glPopMatrix();\r
113                 gl.glMatrixMode(GL.GL_MODELVIEW);\r
114                 gl.glPopMatrix();\r
115                 if (depthTestSave) {\r
116                         gl.glEnable(GL.GL_DEPTH_TEST); // Restore enabled state of depth test.\r
117                 }\r
118                 if (lightingSave) {\r
119                         gl.glEnable(GL.GL_LIGHTING); // Restore enabled state of lighting.\r
120                 }\r
121                 if (texEnvModeSave.get(0) != GL.GL_REPLACE) {\r
122                         gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave.get(0)); // Restore GL texture environment mode.\r
123                 }\r
124                 gl.glEnd();\r
125         }\r
126 \r
127         /**\r
128          * arglDispImageStateful関数モドキ\r
129          * @param image\r
130          * @param zoom\r
131          */\r
132         private void arglDispImageStateful(INyARRgbRaster i_raster, double zoom) throws NyARException\r
133         {\r
134                 javax.media.opengl.GL gl_ = this._gl;\r
135                 final NyARIntSize rsize = i_raster.getSize();\r
136                 float zoomf;\r
137                 IntBuffer params = IntBuffer.allocate(4);\r
138                 zoomf = (float) zoom;\r
139                 gl_.glDisable(GL.GL_TEXTURE_2D);\r
140                 gl_.glGetIntegerv(GL.GL_VIEWPORT, params);\r
141                 gl_.glPixelZoom(zoomf * ((float) (params.get(2)) / (float) rsize.w), -zoomf * ((float) (params.get(3)) / (float) rsize.h));\r
142                 gl_.glWindowPos2f(0.0f, (float) rsize.h);\r
143                 gl_.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);\r
144                 ByteBuffer buf = ByteBuffer.wrap((byte[])i_raster.getBuffer());\r
145                 gl_.glDrawPixels(rsize.w,rsize.h,getGlPixelFormat(i_raster.getBufferType()), GL.GL_UNSIGNED_BYTE, buf);\r
146         }\r
147         \r
148         private double view_scale_factor = 0.025;\r
149         private double view_distance_min = 0.1;//#define VIEW_DISTANCE_MIN              0.1                     // Objects closer to the camera than this will not be displayed.\r
150         private double view_distance_max = 100.0;//#define VIEW_DISTANCE_MAX            100.0           // Objects further away from the camera than this will not be displayed.\r
151 \r
152         public void setScaleFactor(double i_new_value)\r
153         {\r
154                 this.view_scale_factor = i_new_value;\r
155         }\r
156 \r
157         public void setViewDistanceMin(double i_new_value)\r
158         {\r
159                 this.view_distance_min = i_new_value;\r
160         }\r
161 \r
162         public void setViewDistanceMax(double i_new_value)\r
163         {\r
164                 this.view_distance_max = i_new_value;\r
165         }\r
166 \r
167         /**\r
168          * void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])\r
169          * 関数の置き換え\r
170          * NyARParamからOpenGLのProjectionを作成します。\r
171          * @param i_arparam\r
172          * @param o_gl_projection\r
173          * double[16]を指定して下さい。\r
174          */\r
175         public void toCameraFrustumRH(NyARParam i_arparam,double[] o_gl_projection)\r
176         {\r
177                 NyARMat trans_mat = new NyARMat(3, 4);\r
178                 NyARMat icpara_mat = new NyARMat(3, 4);\r
179                 double[][] p = new double[3][3], q = new double[4][4];\r
180                 int i, j;\r
181 \r
182                 final NyARIntSize size=i_arparam.getScreenSize();\r
183                 final int width = size.w;\r
184                 final int height = size.h;\r
185                 \r
186                 i_arparam.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);\r
187 \r
188                 double[][] icpara = icpara_mat.getArray();\r
189                 double[][] trans = trans_mat.getArray();\r
190                 for (i = 0; i < 4; i++) {\r
191                         icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];\r
192                 }\r
193 \r
194                 for (i = 0; i < 3; i++) {\r
195                         for (j = 0; j < 3; j++) {\r
196                                 p[i][j] = icpara[i][j] / icpara[2][2];\r
197                         }\r
198                 }\r
199                 q[0][0] = (2.0 * p[0][0] / (width - 1));\r
200                 q[0][1] = (2.0 * p[0][1] / (width - 1));\r
201                 q[0][2] = -((2.0 * p[0][2] / (width - 1)) - 1.0);\r
202                 q[0][3] = 0.0;\r
203 \r
204                 q[1][0] = 0.0;\r
205                 q[1][1] = -(2.0 * p[1][1] / (height - 1));\r
206                 q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);\r
207                 q[1][3] = 0.0;\r
208 \r
209                 q[2][0] = 0.0;\r
210                 q[2][1] = 0.0;\r
211                 q[2][2] = (view_distance_max + view_distance_min) / (view_distance_min - view_distance_max);\r
212                 q[2][3] = 2.0 * view_distance_max * view_distance_min / (view_distance_min - view_distance_max);\r
213 \r
214                 q[3][0] = 0.0;\r
215                 q[3][1] = 0.0;\r
216                 q[3][2] = -1.0;\r
217                 q[3][3] = 0.0;\r
218 \r
219                 for (i = 0; i < 4; i++) { // Row.\r
220                         // First 3 columns of the current row.\r
221                         for (j = 0; j < 3; j++) { // Column.\r
222                                 o_gl_projection[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];\r
223                         }\r
224                         // Fourth column of the current row.\r
225                         o_gl_projection[i + 3 * 4] = q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];\r
226                 }\r
227                 return;\r
228         }\r
229         \r
230         \r
231         \r
232         /**\r
233          * NyARTransMatResultをOpenGLの行列へ変換します。\r
234          * @param i_ny_result\r
235          * @param o_gl_result\r
236          * @throws NyARException\r
237          */\r
238         public void toCameraViewRH(NyARTransMatResult i_ny_result, double[] o_gl_result) throws NyARException\r
239         {\r
240                 o_gl_result[0 + 0 * 4] = i_ny_result.m00; \r
241                 o_gl_result[0 + 1 * 4] = i_ny_result.m01;\r
242                 o_gl_result[0 + 2 * 4] = i_ny_result.m02;\r
243                 o_gl_result[0 + 3 * 4] = i_ny_result.m03;\r
244                 o_gl_result[1 + 0 * 4] = -i_ny_result.m10;\r
245                 o_gl_result[1 + 1 * 4] = -i_ny_result.m11;\r
246                 o_gl_result[1 + 2 * 4] = -i_ny_result.m12;\r
247                 o_gl_result[1 + 3 * 4] = -i_ny_result.m13;\r
248                 o_gl_result[2 + 0 * 4] = -i_ny_result.m20;\r
249                 o_gl_result[2 + 1 * 4] = -i_ny_result.m21;\r
250                 o_gl_result[2 + 2 * 4] = -i_ny_result.m22;\r
251                 o_gl_result[2 + 3 * 4] = -i_ny_result.m23;\r
252                 o_gl_result[3 + 0 * 4] = 0.0;\r
253                 o_gl_result[3 + 1 * 4] = 0.0;\r
254                 o_gl_result[3 + 2 * 4] = 0.0;\r
255                 o_gl_result[3 + 3 * 4] = 1.0;\r
256                 if (view_scale_factor != 0.0) {\r
257                         o_gl_result[12] *= view_scale_factor;\r
258                         o_gl_result[13] *= view_scale_factor;\r
259                         o_gl_result[14] *= view_scale_factor;\r
260                 }\r
261                 return;\r
262         }       \r
263         \r
264 }\r