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()で済ませる方法はないかしら。

オブジェクトの管理をlua側に移した。
scene.lua

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)