ARToolKit 中のサンプル SimpleTest の方がより基本的なプログラムのようなので、こちらをいじることにします。
mainLoop 中での描画ルーチン draw を Fortran で記述したルーチンに置き換えます。
サンプルを少し書き換えて、立方体の上にワイヤーフレームの球を乗せています。
C 側の変更点は mainLoop 中の draw を、Fortran で記述した draw2 の呼び出しへの書き換えです。
/* get the transformation between the marker and the real camera */
arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans);
draw2();
argSwapBuffers();
}
Fortran 側で厄介なのは、ARToolKit ライブラリのサブルーチンの引数などのインターフェースの記述です。サブルーチンの引き数が、値呼び出しか、参照呼出しか注意が必要です。グローバル変数の扱いは Intel のマニュアル通りでうまく行きます。2次元配列は Fortran と C では行と列が入れ替わっていますのでこれも注意が必要です。
SUBROUTINE draw2() BIND(C) USE, INTRINSIC :: ISO_C_BINDING USE opengl_gl USE opengl_glu USE opengl_glut IMPLICIT NONE ! INTERFACE SUBROUTINE argDrawMode3D() BIND(C) !DEC$ ATTRIBUTES C, DECORATE, ALIAS:'argDrawMode3D' :: argDrawMode3D END SUBROUTINE argDrawMode3D ! SUBROUTINE argDraw3dCamera(ix, iy) BIND(C) USE opengl_gl !DEC$ ATTRIBUTES C, DECORATE, ALIAS:'argDraw3dCamera' :: argDraw3dCamera INTEGER(glcint), VALUE :: ix, iy END SUBROUTINE argDraw3dCamera ! SUBROUTINE argConvGlpara(x, y) BIND(C) USE opengl_gl !DEC$ ATTRIBUTES C, DECORATE, ALIAS:'argConvGlpara' :: argConvGlpara REAL(gldouble) :: x(4, 3), y(4, 4) END SUBROUTINE argConvGlpara END INTERFACE ! ! global variable !DEC$ ATTRIBUTES C, EXTERN :: patt_trans REAL(gldouble) :: patt_trans(4, 3) ! REAL(gldouble) :: gl_para(4, 4) REAL(glfloat ) :: mat_ambient(4) = (/0.0, 0.0, 1.0, 1.0/) REAL(glfloat ) :: mat_flash(4) = (/0.0, 0.0, 1.0, 1.0/) REAL(glfloat ) :: mat_flash_shiny(1) = (/50.0/) REAL(glfloat ) :: light_position(4) = (/100.0,-200.0,200.0,0.0/) REAL(glfloat ) :: ambi(4) = (/0.1, 0.1, 0.1, 0.1/) REAL(glfloat ) :: lightZeroColor(4) = (/0.9, 0.9, 0.9, 0.1/) ! CALL argDrawMode3D() CALL argDraw3dCamera( 0, 0 ) CALL glClearDepth( 1.0_gldouble ) CALL glClear(GL_DEPTH_BUFFER_BIT) CALL glEnable(GL_DEPTH_TEST) CALL glDepthFunc(GL_LEQUAL) ! /* load the camera transformation matrix */ CALL argConvGlpara(patt_trans, gl_para) CALL glMatrixMode(GL_MODELVIEW) CALL glLoadMatrixd( gl_para ) CALL glEnable(GL_LIGHTING) CALL glEnable(GL_LIGHT0) CALL glLightfv(GL_LIGHT0, GL_POSITION, light_position) CALL glLightfv(GL_LIGHT0, GL_AMBIENT, ambi) CALL glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor) CALL glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash) CALL glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny) CALL glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient) CALL glMatrixMode(GL_MODELVIEW) CALL glTranslatef( 0.0_glfloat, 0.0_glfloat, 25.0_glfloat ) CALL glutSolidCube( 50.0_gldouble ) CALL glTranslatef( 0.0_glfloat, 0.0_glfloat, 50.0_glfloat ) CALL glutWireSphere( 30.0_gldouble, 10, 10 ) CALL glDisable( GL_LIGHTING ) CALL glDisable( GL_DEPTH_TEST ) RETURN END SUBROUTINE draw2