Luaを組み込むメモ(その2)
更にCの処理をluaに移動してみた。
toluaに追加
glutのマウス定数とOpenGLの一部をluafunc.pkgに追加。
OpenGL丸ごとバインドしているライブラリもありそうだが。
地味にtypedefが必要だった。
// luafunc.pkg $#include <GL/gl.h> $#include <GL/glut.h> // opengl用のモジュールを作成 module gl { // マクロの値は不要 #define GLUT_LEFT_BUTTON #define GLUT_MIDDLE_BUTTON #define GLUT_RIGHT_BUTTON #define GLUT_DOWN #define GLUT_UP #define GLUT_LEFT #define GLUT_ENTERED #define GL_COLOR_BUFFER_BIT #define GL_DEPTH_BUFFER_BIT #define GL_MODELVIEW typedef unsigned int GLbitfield; // 必要 void glClear (GLbitfield mask); void glLoadIdentity (void); typedef unsigned int GLenum; // 必要 void glMatrixMode (GLenum mode); void glFlush (void); }
luaでオブジェクトとカメラを管理すべくluafunc.pkgに追加。
// luafunc.pkg class HeadPitchCamera { HeadPitchCamera(); // luaでnewするのに必要 void draw(); void head(int dx); void pitch(int dy); }; class VertexArray { VertexArray(); // luaでnewするのに必要 void draw(); void appendVertex(float x, float y, float z); void appendColor(float r, float g, float b); };
Cの関数をluaに移動
とりあえずglutのコールバックを全部移動してみた。
もっと大規模なコードにならないと有り難味が少ないな。
むしろゲームを作ってみるべきか。
// スクリプト実行 void luaf(const char *format, ...) { va_list ap; va_start(ap, format); char luascript[1024]; vsprintf(luascript, format, ap); int ret=luaL_dostring(g_L, luascript); if(ret){ std::cout << "error: " << lua_tostring(g_L, -1) << std::endl; } va_end(ap); } void resize(int w, int h) { luaf("resize(%d, %d)", w, h); } void display() { luaf("display()"); glutSwapBuffers(); } void mouse(int button, int state, int x, int y) { luaf("mouse(%d, %d, %d, %d)",button, state, x, y); } void motion(int x, int y) { luaf("motion(%d, %d)", x, y); // ToDo: 返り値で判定する glutPostRedisplay(); } void keyboard(unsigned char key, int x, int y) { luaf("keyboard(%d)", key); } int main() // の一部 { int ret=luaL_dofile(g_L, "callback.lua"); if(ret){ std::cout << "error: " << lua_tostring(g_L, -1); return 1; } }
callback.lua
require("bit") -- local変数(ファイルローカル?) local mouseRightDown=false local mouseX=-1 local mouseY=-1 -- カメラ管理をluaに移動 local camera=cfunc.HeadPitchCamera:new() -- global scene={} function resize(w, h) cfunc.g_gl:setViewPort(0, 0, w, h); end function display() -- clear scene gl.glClear(bit.bor(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT)); gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); -- set camera camera:draw() -- draw scene for i, v in ipairs(scene) do v:draw() end -- refresh gl.glFlush(); end function keyboard(key) -- Q, q, ESC if key==81 or key==113 or key==27 then cfunc.exit(0) else print(key) end end function mouse(button, state, x, y) if button==gl.GLUT_RIGHT_BUTTON then if state==gl.GLUT_DOWN then mouseRightDown=true mouseX=x mouseY=y else mouseRightDown=false end end end function motion(x, y) if mouseRightDown then camera:head(x-mouseX) camera:pitch(y-mouseY) mouseX=x mouseY=y return true else return false end end
glClearを呼ぶところでluaにbit演算が無いことが発覚。
外部ライブラリbitlibを導入した。
http://luaforge.net/frs/?group_id=224&release_id=934
luaのスタティックライブラリに合体してluaL_openlibs()で済ませる方法はないかしら。
local object=cfunc.VertexArray:new() object:appendVertex(0.0, 1.0, 0.0); object:appendVertex(-1.0, -1.0, 0.0); object:appendVertex(1.0, -1.0, 0.0); object:appendColor(1.0, 0.0, 0.0); object:appendColor(0.0, 1.0, 0.0); object:appendColor(0.0, 0.0, 1.0); table.insert(scene, object)