import java.io.File; import java.io.IOException; import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.media.opengl.GL; import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import javax.media.opengl.glu.GLU; import javax.swing.JFrame; import tangram.GeomElem; import tangram.GeomPoint; import tangram.Tangram; import tangram.svcs.Listios; import com.sun.opengl.util.Animator; import com.sun.opengl.util.BufferUtil; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureIO; public class importjte extends JFrame implements GLEventListener { private GLCanvas canvas; private Animator animator; private GLU glu; private Texture[] texture; static FloatBuffer verticesBuf; static FloatBuffer normalsBuf; static FloatBuffer texcoordBuf; static List bufindexes; static List bufelemofst; static Tangram tan; static float t = 0.0f; static float T = 0.0f; static float zoom = 1/160.f; static float hzw = 15f; static float sw = .0f; public importjte() { glu = new GLU(); canvas = new GLCanvas(new GLCapabilities(GLProfile.getDefault())); canvas.addGLEventListener(this); getContentPane().add(canvas); } public void run() { setSize(320+10, 460+30); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); canvas.requestFocusInWindow(); animator = new Animator(canvas); animator.setRunAsFastAsPossible(false); animator.start(); } public static void main(String[] args) { new importjte().run(); } public void init(GLAutoDrawable drawable) { texture = new Texture[6]; try { texture[0] = TextureIO.newTexture(new File("res/wood1.png"), true); texture[1] = TextureIO.newTexture(new File("res/wood2.png"), true); texture[2] = TextureIO.newTexture(new File("res/wood3.png"), true); texture[3] = TextureIO.newTexture(new File("res/wood4.png"), true); texture[4] = TextureIO.newTexture(new File("res/wood5.png"), true); texture[5] = TextureIO.newTexture(new File("res/wood6.png"), true); } catch (IOException ex) { ex.printStackTrace(); } GL2 gl = drawable.getGL().getGL2(); setupPointers(gl); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); gl.glVertexPointer(3, GL2.GL_FLOAT, 0, verticesBuf); gl.glNormalPointer(GL2.GL_FLOAT, 0, normalsBuf); gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, texcoordBuf); } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL2 gl = drawable.getGL().getGL2(); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(60, (float)width/(float)height, 0.5, 50.0) ; // 視野角[deg] アスペクト比 最近点 最遠い点 gl.glViewport( 0, 0, width , height ); // 左下pxl座標X Y ウィンドウ幅 高さ gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); } public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); float[] lightpos = new float[]{ .2f, .3f, 2f, 1 }; float[] fogcolor = new float[]{ .0f, .0f, .0f, 1 }; gl.glEnable(GL2.GL_FOG); gl.glFogi(GL2.GL_FOG_MODE, GL2.GL_EXP); gl.glFogf(GL2.GL_FOG_DENSITY, 0.2f); gl.glFogfv(GL2.GL_FOG_COLOR, fogcolor, 0); gl.glClearColor(.0f, .0f, .0f, 1.0f); gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); //オブジェクト描画モードにする。 gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); gl.glEnable(GL.GL_TEXTURE_2D); gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); gl.glCullFace(GL2.GL_BACK); gl.glEnable(GL.GL_CULL_FACE); // 光源と材質の設定 gl.glEnable(GL2.GL_COLOR_MATERIAL); gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_DIFFUSE); // カメラ if ((t += 0.025) > 360.0 ) t -= 360.0; glu.gluLookAt( 0, 1, 3f, // 視点の位置x,y,z, 0, 0, 0, // 視界の中心位置の参照点座標x,y,z 0, 1, 0); // 視界の上方向のベクトルx,y,z // 照明 gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_LIGHT0); gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightpos, 0); // 今の座標系を保存しておく gl.glPushMatrix(); //オブジェクトの描画 if ((T += 0.017) > 360.0 ) T -= 360.0; //gl.glRotatef(45, 0, 0, 1); //gl.glRotatef(T, 1, 1, 0); gl.glRotatef(T, 0, 1, 0); //gl.glRotatef(T, 0, (float)Math.cos(T/180*Math.PI), (float)Math.sin(t/180*Math.PI)); drawObj(gl); // 座標系を戻す gl.glPopMatrix(); // コマンドのフラッシュ gl.glFlush(); } private void drawObj(GL2 gl) { int pn, ofst; float x, y, z; float xyr[]; // Tangram int tex[] = {0,4,1,2,1,3,0}; int eno[] = {0,1,1,2,3,4,4}; // Ivy //int tex[] = {0,4,1,2,1,3,0}; //int eno[] = {0,0,1,2,2,3,4}; List li = bufindexes; for (int n = 0; n <= 0; n++) { x=0f; y=0f; z=0f; switch (1) { case 5: // Ivy xyr = new float[] {24.252514264248006f, -2.0632000212564456f, 5.235987755982988f, 38.19995538099002f, 49.98935886200137f, 2.0943951023931953f, 53.22623482261889f, -14.142038346142774f, 2.0943951023931953f, -45.773765177381144f, -21.299714995915696f, 0.0f, -1.7737651773811205f, -45.089479462885116f, 3.141592653589793f, -1.7737651773810974f, 68.41905014797373f, 4.1887902047863905f, -42.65902846763241f, 28.515638303630222f, 4.1887902047863905f }; break; case 6: // Cassowary xyr = new float[] {-13.973723026788404f, 71.02626661534872f, 0.5235987755982988f, 58.02627841180251f, 65.02626197150313f, 5.759586531581287f, -40.000002468417264f, -10.000012826280157f, 0.5235987755982988f, 43.36790971438627f, 22.999987173719816f, 1.5707963267948966f, -7.842325818644314f, 23.698716984497892f, 2.617993877991494f, 99.71876267547214f, -10.000012826280175f, 0.5235987755982988f, -82.65767911819025f, -61.88527611653144f, 5.759586531581287f }; break; default: // Square xyr = new float[] {-51.87572264268514f, -51.9568494554193f, 6.283185307179586f, 40.12427723036572f, -65.95684976960885f, 0.0f, -25.875724352900754f, 0.04315136921091023f, 4.71238898038469f, 0.12427754885441633f, -39.95685052453581f, 6.283185307179586f, -59.87572570350895f, 20.04315052998068f, 0.0f, 56.124276472405825f, 0.0431535191572312f, 6.283185307179586f, 0.12427156723072397f, 56.0431515636766f, 1.5707963267948966f }; break; case 1: case 3: // Confotable Clothe xyr = new float[] {72.01203388576373f, -75.36967666750425f, 3.926991f, 32.011998926016474f, 110.22827536612041f, 3.141592653589793f, -101.01601074434598f, 37.22828367997014f, 2.3561946732051036f, 1.9559518724764224f, -144.77171632002987f, 0f, 12.01199892601648f, 64.22827536612041f, 0f, 16.01202663883157f, -35.77171632002983f, 3.141593f, -31.987999504758708f, 44.22827489535299f, 0f }; break; case 2: case 4: //Penguin Tank xyr = new float[] {-85.78252982505829f, 13.378650525466263f, 2.356194490192345f, -32.04986285770957f, 47.90505637328138f, 4.71238898038469f, -6.0498628577096945f, -119.2320286165663f, 3.141592653589793f, -6.049862857709691f, 7.905056373281291f, 4.71238898038469f, -8.687461827603666f, 147.301222177526f, 1.325354514014773f, -5.647842604156299f, 81.44416161668221f, 3.92699081698724f, -6.451883111263037f, -65.63404887011964f, 0.7853981633974483f }; break; } for (int i = 0; i < 7; i++) { texture[tex[i]].enable(); texture[tex[i]].bind(); gl.glPushMatrix(); gl.glTranslatef(-xyr[i*3]*zoom+x, -xyr[i*3+1]*zoom+y, z); gl.glRotatef(xyr[i*3+2]*180/(float)Math.PI+180, 0, 0, 1); ofst = bufelemofst.get(eno[i]); gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, li.get(ofst+0), pn = li.get(ofst+1)); gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, li.get(ofst+2), pn = li.get(ofst+3)); ofst += 4; for (int j = 0; j < pn*3; j++, ofst += 2) { gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, li.get(ofst), li.get(ofst+1)); } gl.glPopMatrix(); texture[tex[i]].disable(); } } } private void setupPointers(GL2 gl) { tan = new Tangram(); Listios lios = new Listios(); lios.loadXML(tan, "res/tangram100.jte", true, false); int i, j, d, idx = 0, pn; double ox, oy; double x0, y0; double x1, y1; double nx0, ny0; double nx1, ny1; double dx, dy; double l; double tdx, tdy; double[] ix, iy; double[] sx, sy; GeomElem ge; List gp; boolean etgl; boolean ldsc; bufindexes = new ArrayList(100); bufelemofst = new ArrayList(10); float vertices[] = new float[3*(2*3+4*3)*20]; float normals[] = new float[3*(2*3+4*3)*20]; float texcoord[] = new float[3*(2*3+4*3)*20]; for (Iterator gei = tan.geombank.geombank.iterator(); gei.hasNext();) { ge = gei.next(); gp = ge.geompoints; pn = gp.size(); ox = ge.local_ox; oy = ge.local_oy; bufelemofst.add(bufindexes.size()); // 頂点抽出 ix = new double[pn]; iy = new double[pn]; for (i = 0; i < pn; i++) { ix[i] = gp.get(i).x[0]; iy[i] = gp.get(i).y[0]; } // 始点と終点が同じなら、頂点数-1 if ((ix[0] == ix[pn-1]) && (iy[0] == iy[pn-1])) pn--; // 縮小頂点抽出 sx = new double[pn]; sy = new double[pn]; for (i = 0; i < pn; i++) { dx = ix[(i+1)%pn] - ix[i]; dy = iy[(i+1)%pn] - iy[i]; l = Math.sqrt(dx*dx + dy*dy); nx0 = dy/l; ny0 = -dx/l; dx = ix[i] - ix[(pn+i-1)%pn]; dy = iy[i] - iy[(pn+i-1)%pn]; l = Math.sqrt(dx*dx + dy*dy); nx1 = dy/l; ny1 = -dx/l; l = sw*Math.sqrt(2) / (1 + (nx0*nx1 + ny0*ny1)); sx[i] = ix[i] + l*(nx0 + nx1); sy[i] = iy[i] + l*(ny0 + ny1); } // 表面・裏面 bufindexes.add(idx); for (i = 0, d = 0, etgl = true; i < pn; i++, etgl = !etgl, idx++) { x0 = ( etgl) ? sx[d] : sx[(pn - d) % pn]; y0 = ( etgl) ? sy[d] : sy[(pn - d) % pn]; x1 = (!etgl) ? sx[d] : sx[(pn - d) % pn]; y1 = (!etgl) ? sy[d] : sy[(pn - d) % pn]; if (etgl) d++; // 表面 vertices[idx*3+0] = (float)(x0 - ox); vertices[idx*3+1] = (float)(y0 - oy); vertices[idx*3+2] = hzw; texcoord[idx*2+0] = (float)x0; texcoord[idx*2+1] = (float)y0; normals[idx*3+0] = 0; normals[idx*3+1] = 0; normals[idx*3+2] = 1; // 裏面 vertices[(idx+pn)*3+0] = (float)(x1 - ox); vertices[(idx+pn)*3+1] = (float)(y1 - oy); vertices[(idx+pn)*3+2] = -hzw; texcoord[(idx+pn)*2+0] = (float)x1; texcoord[(idx+pn)*2+1] = (float)y1; normals[(idx+pn)*3+0] = 0; normals[(idx+pn)*3+1] = 0; normals[(idx+pn)*3+2] = -1; } bufindexes.add(i); bufindexes.add(idx); bufindexes.add(i); idx += i; // 側面 for (i = 0; i < pn; i++) { // 側面 bufindexes.add(idx); x0 = ix[i]; y0 = iy[i]; x1 = ix[(i + 1) % pn]; y1 = iy[(i + 1) % pn]; dx = x1 - x0; dy = y1 - y0; l = Math.sqrt(dx*dx + dy*dy); ldsc = (Math.abs(dx) > Math.abs(dy)); tdx = (ldsc) ? l : hzw*2; tdy = (ldsc) ? hzw*2 : l; for (j = 0, etgl = true; j < 4; j++, etgl = !etgl, idx++) { vertices[idx*3+0] = (float)(((etgl) ? x0 : x1) - ox); vertices[idx*3+1] = (float)(((etgl) ? y0 : y1) - oy); vertices[idx*3+2] = (j < 2) ? hzw-sw : -hzw+sw; texcoord[idx*2+0] = (float)((etgl) ? ((ldsc) ? 0 : ((j < 2) ? 0 : tdx)) : ((ldsc) ? tdx : ((j < 2) ? 0 : tdx))); texcoord[idx*2+1] = (float)((etgl) ? ((ldsc) ? ((j < 2) ? 0 : tdy) : 0) : ((ldsc) ? ((j < 2) ? 0 : tdy) : tdy)); normals[idx*3+0] = (float)(dy/l); normals[idx*3+1] = (float)(-dx/l); normals[idx*3+2] = 0; } bufindexes.add(j); // 上下側面 bufindexes.add(idx); for (j = 0, etgl = true; j < 4; j++, etgl = !etgl, idx++) { dx = ix[(i + 1) % pn] - ix[i]; dy = iy[(i + 1) % pn] - iy[i]; l = Math.sqrt(dx*dx + dy*dy); x0 = (j >= 2) ? ix[i] : sx[i]; y0 = (j >= 2) ? iy[i] : sy[i]; x1 = (j >= 2) ? ix[(i + 1) % pn] : sx[(i + 1) % pn]; y1 = (j >= 2) ? iy[(i + 1) % pn] : sy[(i + 1) % pn]; vertices[idx*3+0] = (float)(((etgl) ? x0 : x1) - ox); vertices[idx*3+1] = (float)(((etgl) ? y0 : y1) - oy); vertices[idx*3+2] = (j < 2) ? hzw : hzw-sw; texcoord[idx*2+0] = (float)((etgl) ? x0 : x1); texcoord[idx*2+1] = (float)((etgl) ? y0 : y1); /* normals[idx*3+0] = (float)((j < 2) ? 0 : dy/l); normals[idx*3+1] = (float)((j < 2) ? 0 : -dx/l); normals[idx*3+2] = (float)((j < 2) ? 1 : 0); */ normals[idx*3+0] = (float)(dy/l/Math.sqrt(2)); normals[idx*3+1] = (float)(-dx/l/Math.sqrt(2)); normals[idx*3+2] = (float)(.5/Math.sqrt(2)); x0 = (j < 2) ? ix[i] : sx[i]; y0 = (j < 2) ? iy[i] : sy[i]; x1 = (j < 2) ? ix[(i + 1) % pn] : sx[(i + 1) % pn]; y1 = (j < 2) ? iy[(i + 1) % pn] : sy[(i + 1) % pn]; vertices[(idx+4)*3+0] = (float)(((etgl) ? x0 : x1) - ox); vertices[(idx+4)*3+1] = (float)(((etgl) ? y0 : y1) - oy); vertices[(idx+4)*3+2] = (j >= 2) ? -hzw : -hzw+sw; texcoord[(idx+4)*2+0] = (float)((etgl) ? x0 : x1); texcoord[(idx+4)*2+1] = (float)((etgl) ? y0 : y1); /* normals[(idx+4)*3+0] = (float)((j >= 2) ? 0 : dy/l); normals[(idx+4)*3+1] = (float)((j >= 2) ? 0 : -dx/l); normals[(idx+4)*3+2] = (float)((j >= 2) ? -1 : 0); */ normals[(idx+4)*3+0] = (float)(dy/l/Math.sqrt(2)); normals[(idx+4)*3+1] = (float)(-dx/l/Math.sqrt(2)); normals[(idx+4)*3+2] = (float)(-.5/Math.sqrt(2)); } bufindexes.add(j); bufindexes.add(idx); bufindexes.add(j); idx += j; } } this.verticesBuf = mkFloatBuf(vertices, zoom); this.normalsBuf = mkFloatBuf(normals, 1.0f); this.texcoordBuf = mkFloatBuf(texcoord, zoom); } private FloatBuffer mkFloatBuf(float[] vertices, float ratio) { FloatBuffer tmpVerticesBuf = BufferUtil.newFloatBuffer(vertices.length); for (int i = 0; i < vertices.length; i++) tmpVerticesBuf.put(vertices[i] * ratio); tmpVerticesBuf.rewind(); return tmpVerticesBuf; } public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void dispose(GLAutoDrawable drawable){} }