/
NyARGLDrawUtil.java
311 lines (303 loc) · 12.7 KB
/
NyARGLDrawUtil.java
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
package jp.nyatla.nyartoolkit.jogl.utils;
import java.awt.Color;
import java.awt.Font;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import javax.media.opengl.GL;
import jp.nyatla.nyartoolkit.core.NyARRuntimeException;
import jp.nyatla.nyartoolkit.core.raster.INyARRaster;
import jp.nyatla.nyartoolkit.core.raster.rgb.INyARRgbRaster;
import jp.nyatla.nyartoolkit.core.types.NyARBufferType;
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
import com.sun.opengl.util.j2d.TextRenderer;
/**
* このクラスには、アプリケーションの為のOpenGL用のヘルパー関数を定義します。
* NyARToolKitを使ったアプリケーションを実装するのに役立ちます。
* ほとんどの関数はstatic宣言です。このクラスのインスタンスを作る必要はありません。
*
*
*/
public class NyARGLDrawUtil
{
private static TextRenderer _tr=new TextRenderer(new Font("SansSerif", Font.PLAIN, 10));
private static float[][] COLORCUBE_COLOR= 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 } };
private static 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 } };
private static short[][] CUBE_FACE = 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 } };
public static void drawCube(GL i_gl,float i_size_per_mm,float i_r,float i_g,float i_b)
{
float v[]={i_r,i_g,i_b};
float vs[][]={v,v,v,v,v,v,v,v};
drawColorCube(i_gl,i_size_per_mm,vs);
}
/**
* この関数は、指定サイズの立方体を現在のビューポートへ描画します。
* ARToolKitのサンプルで使われているカラーキューブを描画します。
* @param i_gl
* OpenGLのインスタンス
* @param i_size_per_mm
* 立方体の辺の長さ。[mm単位]
* ARシステムをmmオーダーで構築していない場合は、別単位になります。
*/
public static void drawColorCube(GL i_gl,float i_size_per_mm)
{
drawColorCube(i_gl,i_size_per_mm,COLORCUBE_COLOR);
}
private static void drawColorCube(GL i_gl,float i_size_per_mm,float[][] i_color)
{
// Colour cube data.
int polyList = 0;
float fSize =i_size_per_mm/2f;
int f, i;
int cube_num_faces = 6;
if (polyList == 0) {
polyList = i_gl.glGenLists(1);
i_gl.glNewList(polyList, GL.GL_COMPILE);
i_gl.glBegin(GL.GL_QUADS);
for (f = 0; f < cube_num_faces; f++)
for (i = 0; i < 4; i++) {
i_gl.glColor3f(i_color[CUBE_FACE[f][i]][0], i_color[CUBE_FACE[f][i]][1], i_color[CUBE_FACE[f][i]][2]);
i_gl.glVertex3f(CUBE_VERTICES[CUBE_FACE[f][i]][0] * fSize, CUBE_VERTICES[CUBE_FACE[f][i]][1] * fSize, CUBE_VERTICES[CUBE_FACE[f][i]][2] * fSize);
}
i_gl.glEnd();
i_gl.glColor3f(0.0f, 0.0f, 0.0f);
for (f = 0; f < cube_num_faces; f++) {
i_gl.glBegin(GL.GL_LINE_LOOP);
for (i = 0; i < 4; i++)
i_gl.glVertex3f(CUBE_VERTICES[CUBE_FACE[f][i]][0] * fSize, CUBE_VERTICES[CUBE_FACE[f][i]][1] * fSize, CUBE_VERTICES[CUBE_FACE[f][i]][2] * fSize);
i_gl.glEnd();
}
i_gl.glEndList();
}
i_gl.glCallList(polyList); // Draw the cube.
}
/**
* この関数は、{@link NyARGLDrawUtil}の描画する文字列の、フォントカラーを設定します。
* フォントカラーはOpenGL固有のものではなく、{@link NyARGLDrawUtil}固有のものです。
* @param i_c
* 設定する色。
*/
public static void setFontColor(Color i_c)
{
NyARGLDrawUtil._tr.setColor(i_c);
}
/**
* この関数は、{@link NyARGLDrawUtil}の描画する文字列の、フォントスタイルを設定します。
* フォントスタイルはOpenGL固有のものではなく、{@link NyARGLDrawUtil}固有のものです。
* @param i_font_name
* フォントの名前を指定します。デフォルト値は、"SansSerif"です。
* @param i_font_style
* フォントスタイルを指定します。デフォルト値は、{@link Font#PLAIN}です。
* @param i_size
* フォントサイズを指定します。デフォルト値は、10です。
*/
public static void setFontStyle(String i_font_name,int i_font_style,int i_size)
{
NyARGLDrawUtil._tr=new TextRenderer(new Font(i_font_name,i_font_style, i_size));
}
/**
* この関数は、文字列を描画します。
* この関数は、ちらつきが発生したり、あまり品質が良くありません。品質を求められる環境では、別途実装をして下さい。
* @param i_str
* 描画する文字列。
* @param i_scale
* 文字列のスケール値。
*/
public static void drawText(String i_str,float i_scale)
{
NyARGLDrawUtil._tr.begin3DRendering();
NyARGLDrawUtil._tr.draw3D(i_str, 0f,0f,0f,i_scale);
NyARGLDrawUtil._tr.end3DRendering();
return;
}
/**
* この関数は、{@link INyARRaster}の内容を、現在のビューポートへ描画します。
* カメラ画像の背景を描画するのに使用できます。
* @param i_gl
* OpenGLのインスタンス
* @param i_raster
* 描画するラスタオブジェクト。何れかのバッファ形式である必要があります。
* <ol>
* <li>{@link NyARBufferType#BYTE1D_B8G8R8_24}
* <li>{@link NyARBufferType#BYTE1D_R8G8B8_24}
* <li>{@link NyARBufferType#BYTE1D_B8G8R8X8_32}
* </ol>
* @param i_zoom
* @throws NyARRuntimeException
*/
public static void drawBackGround(GL i_gl,INyARRaster i_raster, double i_zoom) throws NyARRuntimeException
{
IntBuffer texEnvModeSave = IntBuffer.allocate(1);
boolean lightingSave;
boolean depthTestSave;
final NyARIntSize rsize=i_raster.getSize();
// Prepare an orthographic projection, set camera position for 2D drawing, and save GL state.
i_gl.glGetTexEnviv(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave); // Save GL texture environment mode.
if (texEnvModeSave.array()[0] != GL.GL_REPLACE) {
i_gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
}
lightingSave = i_gl.glIsEnabled(GL.GL_LIGHTING); // Save enabled state of lighting.
if (lightingSave == true) {
i_gl.glDisable(GL.GL_LIGHTING);
}
depthTestSave = i_gl.glIsEnabled(GL.GL_DEPTH_TEST); // Save enabled state of depth test.
if (depthTestSave == true) {
i_gl.glDisable(GL.GL_DEPTH_TEST);
}
//ProjectionMatrixとModelViewMatrixを初期化
i_gl.glMatrixMode(GL.GL_PROJECTION);
i_gl.glPushMatrix();
i_gl.glLoadIdentity();
i_gl.glOrtho(0.0,rsize.w, 0.0,rsize.h,0,1);
i_gl.glMatrixMode(GL.GL_MODELVIEW);
i_gl.glPushMatrix();
i_gl.glLoadIdentity();
arglDispImageStateful(i_gl,rsize,i_raster.getBuffer(),i_raster.getBufferType(),i_zoom);
//ProjectionMatrixとModelViewMatrixを回復
i_gl.glMatrixMode(GL.GL_PROJECTION);
i_gl.glPopMatrix();
i_gl.glMatrixMode(GL.GL_MODELVIEW);
i_gl.glPopMatrix();
if (depthTestSave) {
i_gl.glEnable(GL.GL_DEPTH_TEST); // Restore enabled state of depth test.
}
if (lightingSave) {
i_gl.glEnable(GL.GL_LIGHTING); // Restore enabled state of lighting.
}
if (texEnvModeSave.get(0) != GL.GL_REPLACE) {
i_gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, texEnvModeSave.get(0)); // Restore GL texture environment mode.
}
i_gl.glEnd();
}
/**
* この関数は、指定したラスタを現在の座標系の平面に描画します。
* @param i_gl
* @param i_x
* @param i_y
* @param i_raster
* @throws NyARRuntimeException
*/
public static void drawRaster(GL i_gl,INyARRgbRaster i_raster) throws NyARRuntimeException
{
NyARIntSize s=i_raster.getSize();
int[] n=new int[1];
float[] color=new float[3];
boolean old_is_texture_2d=i_gl.glIsEnabled(GL.GL_TEXTURE_2D);
i_gl.glGetFloatv(GL.GL_CURRENT_COLOR,color,0);//カラーの退避
i_gl.glColor3f(1,1,1);
i_gl.glEnable(GL.GL_TEXTURE_2D);
i_gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
i_gl.glGenTextures(1,n,0);
i_gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
i_gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
switch(i_raster.getBufferType())
{
case NyARBufferType.BYTE1D_R8G8B8_24:
i_gl.glTexImage2D(GL.GL_TEXTURE_2D,0, GL.GL_RGB,s.w,s.h,0,GL.GL_RGB,GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_raster.getBuffer()));
break;
case NyARBufferType.BYTE1D_B8G8R8_24:
i_gl.glTexImage2D(GL.GL_TEXTURE_2D,0, GL.GL_RGB,s.w,s.h,0,GL.GL_BGR,GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_raster.getBuffer()));
break;
case NyARBufferType.BYTE1D_B8G8R8X8_32:
i_gl.glTexImage2D(GL.GL_TEXTURE_2D,0, GL.GL_RGB,s.w,s.h,0,GL.GL_BGRA,GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_raster.getBuffer()));
break;
case NyARBufferType.INT1D_X8R8G8B8_32:
i_gl.glTexImage2D(GL.GL_TEXTURE_2D,0, GL.GL_RGB,s.w,s.h,0,GL.GL_BGRA,GL.GL_UNSIGNED_BYTE, IntBuffer.wrap((int[])i_raster.getBuffer()));
break;
default:
throw new NyARRuntimeException();
}
i_gl.glBegin(GL.GL_QUADS);
i_gl.glBindTexture(GL.GL_TEXTURE_2D,n[0]);
i_gl.glTexCoord2f(0,0);i_gl.glVertex3f(0,0,0);
i_gl.glTexCoord2f(1,0);i_gl.glVertex3f(s.w,0,0);
i_gl.glTexCoord2f(1,1);i_gl.glVertex3f(s.w,s.h,0);
i_gl.glTexCoord2f(0,1);i_gl.glVertex3f(0,s.h,0);
i_gl.glEnd();
i_gl.glDeleteTextures(1,n,0);
if(!old_is_texture_2d){
i_gl.glDisable(GL.GL_TEXTURE_2D);
}
i_gl.glColor3fv(color,0);//カラーの復帰
}
/**
* arglDispImageStateful関数モドキ
* @param image
* @param zoom
*/
private static void arglDispImageStateful(GL gl,NyARIntSize i_size,Object i_buffer,int i_buffer_type, double zoom) throws NyARRuntimeException
{
float zoomf;
IntBuffer params = IntBuffer.allocate(4);
zoomf = (float) zoom;
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glGetIntegerv(GL.GL_VIEWPORT, params);
gl.glPixelZoom(zoomf * ((float) (params.get(2)) / (float) i_size.w), -zoomf * ((float) (params.get(3)) / (float) i_size.h));
gl.glWindowPos2f(0.0f, (float) i_size.h);
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
//BufferTypeの変換
switch(i_buffer_type)
{
case NyARBufferType.BYTE1D_B8G8R8_24:
gl.glDrawPixels(i_size.w,i_size.h,GL.GL_BGR, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));
break;
case NyARBufferType.BYTE1D_R8G8B8_24:
gl.glDrawPixels(i_size.w,i_size.h,GL.GL_RGB, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));
break;
case NyARBufferType.BYTE1D_B8G8R8X8_32:
gl.glDrawPixels(i_size.w,i_size.h,GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])i_buffer));
break;
case NyARBufferType.INT1D_X8R8G8B8_32:
gl.glDrawPixels(i_size.w,i_size.h,GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, IntBuffer.wrap((int[])i_buffer));
break;
case NyARBufferType.INT1D_GRAY_8:
/** @bug RED screen*/
gl.glDrawPixels(i_size.w,i_size.h,GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, IntBuffer.wrap((int[])i_buffer));
break;
default:
throw new NyARRuntimeException();
}
}
/**
* この関数は、スクリーン座標系をOpenGLにロードします。
* スクリーンに二次元系の情報をそのまま書きこむときに使います。
* この関数は、PROJECTIONとMODELVIEWスタックをそれぞれ1づつpushします。
* スクリーン座標系を使用し終わったら、{@link #endScreenCoordinateSystem}を必ず呼び出してください。
* @param i_gl
* OpenGLのインスタンス
* @param i_width
* スクリーンの幅
* @param i_height
* スクリーンの高さ
* @param i_revers_y_direction
* Y軸の反転フラグ。trueならばtop->bottom、falseならばbottom->top方向になります。
*/
public static void beginScreenCoordinateSystem(GL i_gl,int i_width,int i_height,boolean i_revers_y_direction)
{
i_gl.glMatrixMode(GL.GL_PROJECTION);
i_gl.glPushMatrix(); // Save world coordinate system.
i_gl.glLoadIdentity();
if(i_revers_y_direction){
i_gl.glOrtho(0.0,i_width,i_height,0,-1,1);
}else{
i_gl.glOrtho(0.0,i_width,0,i_height,-1,1);
}
i_gl.glMatrixMode(GL.GL_MODELVIEW);
i_gl.glPushMatrix(); // Save world coordinate system.
i_gl.glLoadIdentity();
return;
}
/**
* この関数は、ロードしたスクリーン座標系を元に戻します。
* {@link #beginScreenCoordinateSystem}の後に呼び出してください。
* @param i_gl
* OpenGLのインスタンス
*/
public static void endScreenCoordinateSystem(GL i_gl)
{
i_gl.glMatrixMode(GL.GL_PROJECTION);
i_gl.glPopMatrix();
i_gl.glMatrixMode(GL.GL_MODELVIEW);
i_gl.glPopMatrix();
return;
}
}