--- /dev/null
+package jp.nyatla.nyartoolkit.jogl.utils;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.nio.ByteBuffer;\r
+import java.nio.IntBuffer;\r
+\r
+import javax.media.opengl.GL;\r
+\r
+import jp.nyatla.nyartoolkit.NyARException;\r
+import jp.nyatla.nyartoolkit.core.raster.INyARRaster;\r
+import jp.nyatla.nyartoolkit.core.types.NyARBufferType;\r
+import jp.nyatla.nyartoolkit.core.types.NyARIntSize;\r
+\r
+import com.sun.opengl.util.j2d.TextRenderer;\r
+\r
+/**\r
+ * このクラスには、アプリケーションの為のOpenGL用のヘルパー関数を定義します。\r
+ * NyARToolKitを使ったアプリケーションを実装するのに役立ちます。\r
+ * ほとんどの関数はstatic宣言です。このクラスのインスタンスを作る必要はありません。\r
+ * \r
+ *\r
+ */\r
+public class NyARGLDrawUtil\r
+{\r
+ private static TextRenderer _tr=new TextRenderer(new Font("SansSerif", Font.PLAIN, 10));\r
+ /**\r
+ * この関数は、指定サイズの立方体を現在のビューポートへ描画します。\r
+ * ARToolKitのサンプルで使われているカラーキューブを描画します。\r
+ * @param i_gl\r
+ * OpenGLのインスタンス\r
+ * @param i_size_per_mm\r
+ * 立方体の辺の長さ。[mm単位]\r
+ * ARシステムをmmオーダーで構築していない場合は、別単位になります。\r
+ */\r
+ public static void drawColorCube(GL i_gl,float i_size_per_mm)\r
+ {\r
+ // Colour cube data.\r
+ int polyList = 0;\r
+ float fSize =i_size_per_mm/2f;\r
+ int f, i;\r
+ float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f }, { 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f } };\r
+ float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };\r
+ int cube_num_faces = 6;\r
+ short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 }, { 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };\r
+\r
+ if (polyList == 0) {\r
+ polyList = i_gl.glGenLists(1);\r
+ i_gl.glNewList(polyList, GL.GL_COMPILE);\r
+ i_gl.glBegin(GL.GL_QUADS);\r
+ for (f = 0; f < cube_num_faces; f++)\r
+ for (i = 0; i < 4; i++) {\r
+ i_gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);\r
+ i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ }\r
+ i_gl.glEnd();\r
+ i_gl.glColor3f(0.0f, 0.0f, 0.0f);\r
+ for (f = 0; f < cube_num_faces; f++) {\r
+ i_gl.glBegin(GL.GL_LINE_LOOP);\r
+ for (i = 0; i < 4; i++)\r
+ i_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);\r
+ i_gl.glEnd();\r
+ }\r
+ i_gl.glEndList();\r
+ }\r
+ i_gl.glCallList(polyList); // Draw the cube.\r
+ }\r
+ /**\r
+ * この関数は、{@link NyARGLDrawUtil}の描画する文字列の、フォントカラーを設定します。\r
+ * フォントカラーはOpenGL固有のものではなく、{@link NyARGLDrawUtil}固有のものです。\r
+ * @param i_c\r
+ * 設定する色。\r
+ */\r
+ public static void setFontColor(Color i_c)\r
+ {\r
+ NyARGLDrawUtil._tr.setColor(i_c);\r
+ }\r
+ /**\r
+ * この関数は、{@link NyARGLDrawUtil}の描画する文字列の、フォントスタイルを設定します。\r
+ * フォントスタイルはOpenGL固有のものではなく、{@link NyARGLDrawUtil}固有のものです。\r
+ * @param i_font_name\r
+ * フォントの名前を指定します。デフォルト値は、"SansSerif"です。\r
+ * @param i_font_style\r
+ * フォントスタイルを指定します。デフォルト値は、{@link Font#PLAIN}です。\r
+ * @param i_size\r
+ * フォントサイズを指定します。デフォルト値は、10です。\r
+ */\r
+ public static void setFontStyle(String i_font_name,int i_font_style,int i_size)\r
+ {\r
+ NyARGLDrawUtil._tr=new TextRenderer(new Font(i_font_name,i_font_style, i_size));\r
+ }\r
+ /**\r
+ * この関数は、文字列を描画します。\r
+ * この関数は、ちらつきが発生したり、あまり品質が良くありません。品質を求められる環境では、別途実装をして下さい。\r
+ * @param i_str\r
+ * 描画する文字列。\r
+ * @param i_scale\r
+ * 文字列のスケール値。\r
+ */\r
+ public static void drawText(String i_str,float i_scale)\r
+ {\r
+ NyARGLDrawUtil._tr.begin3DRendering();\r
+ NyARGLDrawUtil._tr.draw3D(i_str, 0f,0f,0f,i_scale);\r
+ NyARGLDrawUtil._tr.end3DRendering();\r
+ return;\r
+ }\r
+ /**\r
+ * この関数は、{@link INyARRaster}の内容を、現在のビューポートへ描画します。\r
+ * カメラ画像の背景を描画するのに使用できます。\r
+ * @param i_gl\r
+ * OpenGLのインスタンス\r
+ * @param i_raster\r
+ * 描画するラスタオブジェクト。何れかのバッファ形式である必要があります。\r
+ * <ol>\r
+ * <li>{@link NyARBufferType#BYTE1D_B8G8R8_24}\r
+ * <li>{@link NyARBufferType#BYTE1D_R8G8B8_24}\r
+ * <li>{@link NyARBufferType#BYTE1D_B8G8R8X8_32}\r
+ * </ol>\r
+ * @param i_zoom\r
+ * @throws NyARException\r
+ */\r
+ public static void drawBackGround(javax.media.opengl.GL i_gl,INyARRaster i_raster, double i_zoom) throws NyARException\r
+ {\r
+ IntBuffer texEnvModeSave = IntBuffer.allocate(1);\r
+ boolean lightingSave;\r
+ boolean depthTestSave;\r
+ final NyARIntSize rsize=i_raster.getSize();\r
+ // Prepare an orthographic projection, set camera position for 2D drawing, and save GL state.\r
+ i_gl.glGetTexEnviv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave); // Save GL texture environment mode.\r
+ if (texEnvModeSave.array()[0] != GL.GL_REPLACE) {\r
+ i_gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);\r
+ }\r
+ lightingSave = i_gl.glIsEnabled(GL.GL_LIGHTING); // Save enabled state of lighting.\r
+ if (lightingSave == true) {\r
+ i_gl.glDisable(GL.GL_LIGHTING);\r
+ }\r
+ depthTestSave = i_gl.glIsEnabled(GL.GL_DEPTH_TEST); // Save enabled state of depth test.\r
+ if (depthTestSave == true) {\r
+ i_gl.glDisable(GL.GL_DEPTH_TEST);\r
+ }\r
+ //ProjectionMatrixとModelViewMatrixを初期化\r
+ i_gl.glMatrixMode(GL.GL_PROJECTION);\r
+ i_gl.glPushMatrix();\r
+ i_gl.glLoadIdentity();\r
+ i_gl.glOrtho(0.0,rsize.w, 0.0,rsize.h,0,1);\r
+ i_gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ i_gl.glPushMatrix();\r
+ i_gl.glLoadIdentity();\r
+ arglDispImageStateful(i_gl,rsize,i_raster.getBuffer(),i_raster.getBufferType(),i_zoom);\r
+ //ProjectionMatrixとModelViewMatrixを回復\r
+ i_gl.glMatrixMode(GL.GL_PROJECTION);\r
+ i_gl.glPopMatrix();\r
+ i_gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ i_gl.glPopMatrix();\r
+ if (depthTestSave) {\r
+ i_gl.glEnable(GL.GL_DEPTH_TEST); // Restore enabled state of depth test.\r
+ }\r
+ if (lightingSave) {\r
+ i_gl.glEnable(GL.GL_LIGHTING); // Restore enabled state of lighting.\r
+ }\r
+ if (texEnvModeSave.get(0) != GL.GL_REPLACE) {\r
+ i_gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave.get(0)); // Restore GL texture environment mode.\r
+ }\r
+ i_gl.glEnd();\r
+ }\r
+\r
+ /**\r
+ * arglDispImageStateful関数モドキ\r
+ * @param image\r
+ * @param zoom\r
+ */\r
+ private static void arglDispImageStateful(GL gl,NyARIntSize i_size,Object i_buffer,int i_buffer_type, double zoom) throws NyARException\r
+ {\r
+ float zoomf;\r
+ IntBuffer params = IntBuffer.allocate(4);\r
+ zoomf = (float) zoom;\r
+ gl.glDisable(GL.GL_TEXTURE_2D);\r
+ gl.glGetIntegerv(GL.GL_VIEWPORT, params);\r
+ gl.glPixelZoom(zoomf * ((float) (params.get(2)) / (float) i_size.w), -zoomf * ((float) (params.get(3)) / (float) i_size.h));\r
+ gl.glWindowPos2f(0.0f, (float) i_size.h);\r
+ gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);\r
+ //BufferTypeの変換\r
+ switch(i_buffer_type)\r
+ {\r
+ case NyARBufferType.BYTE1D_B8G8R8_24:\r
+ gl.glDrawPixels(i_size.w,i_size.h,GL.GL_BGR, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));\r
+ break;\r
+ case NyARBufferType.BYTE1D_R8G8B8_24:\r
+ gl.glDrawPixels(i_size.w,i_size.h,GL.GL_RGB, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));\r
+ break;\r
+ case NyARBufferType.BYTE1D_B8G8R8X8_32:\r
+ gl.glDrawPixels(i_size.w,i_size.h,GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));\r
+ break;\r
+ case NyARBufferType.INT1D_GRAY_8:\r
+ /** @bug don't work*/\r
+ gl.glDrawPixels(i_size.w,i_size.h,GL.GL_LUMINANCE, GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[])i_buffer));\r
+ break;\r
+ default:\r
+ throw new NyARException();\r
+ }\r
+ }\r
+ /**\r
+ * この関数は、スクリーン座標系をOpenGLにロードします。\r
+ * スクリーンに二次元系の情報をそのまま書きこむときに使います。\r
+ * この関数は、PROJECTIONとMODELVIEWスタックをそれぞれ1づつpushします。\r
+ * スクリーン座標系を使用し終わったら、{@link #endScreenCoordinateSystem}を必ず呼び出してください。\r
+ * @param i_gl\r
+ * OpenGLのインスタンス\r
+ * @param i_width\r
+ * スクリーンの幅\r
+ * @param i_height\r
+ * スクリーンの高さ\r
+ * @param i_revers_y_direction\r
+ * Y軸の反転フラグ。trueならばtop->bottom、falseならばbottom->top方向になります。\r
+ */\r
+ public static void beginScreenCoordinateSystem(GL i_gl,int i_width,int i_height,boolean i_revers_y_direction)\r
+ {\r
+ i_gl.glMatrixMode(GL.GL_PROJECTION);\r
+ i_gl.glPushMatrix(); // Save world coordinate system.\r
+ i_gl.glLoadIdentity();\r
+ if(i_revers_y_direction){\r
+ i_gl.glOrtho(0.0,i_width,i_height,0,-1,1);\r
+ }else{\r
+ i_gl.glOrtho(0.0,i_width,0,i_height,-1,1);\r
+ }\r
+ i_gl.glMatrixMode(GL.GL_MODELVIEW);\r
+ i_gl.glPushMatrix(); // Save world coordinate system.\r
+ i_gl.glLoadIdentity();\r
+ return;\r
+ }\r
+ /**\r
+ * この関数は、ロードしたスクリーン座標系を元に戻します。\r
+ * {@link #beginScreenCoordinateSystem}の後に呼び出してください。\r
+ * @param i_gl\r
+ * OpenGLのインスタンス\r
+ */\r
+ public static void endScreenCoordinateSystem(GL i_gl)\r
+ {\r
+ i_gl.glMatrixMode(GL.GL_PROJECTION);\r
+ i_gl.glPopMatrix();\r
+ i_gl.glMatrixMode(GL.GL_MODELVIEW); \r
+ i_gl.glPopMatrix();\r
+ return;\r
+ } \r
+}\r