extern "C" { #include #include #include } #include #include #include #include #include #include #include #pragma comment(lib,"opengl32.lib") using namespace std; HWND g_hWnd = NULL; namespace rch { class OpenGL { protected: HWND m_hWnd; HDC m_hDC; HGLRC m_hRC; public: OpenGL(); virtual ~OpenGL(); void init(HWND hWnd); void setupPixelFormat(HDC hdc); void swapBuffer(); void cleanup(); void begin(); void end(); }; class Object { protected: float m_X; float m_Y; float m_Time; public: Object(); virtual ~Object(); void setPos(float x, float y); float getX() { return m_X; } void setX(float x); float getY() { return m_Y; } void setY(float y); float getTime() { return m_Time; } void setTime(float t); void incTime(float dt); virtual void run(); }; class Object2 : public Object { protected: std::string m_sFuncName; public: Object2(); virtual ~Object2(); std::string getFunc(void) { return m_sFuncName; } void setFunc(const std::string& sFuncName); virtual void run(); }; } //********************************************************** rch::OpenGL gl; lua_State* L; typedef std::auto_ptr ObjPtr; std::list apObj; typedef std::list::iterator ObjPtrItr; //********************************************************** void putTriangle(float x, float y) { glBegin(GL_TRIANGLES); glColor4f(0.1f, 0.f, 0.f, 0.1f); glVertex2f(-0.05f + x, -0.05f + y); glVertex2f( 0.05f + x, -0.05f + y); glColor4f(1.f, 1.f, 0.f, 1.0f); glVertex2f( 0.f + x, 0.1f + y); glEnd(); } //********************************************************** int luafPutTriangle(lua_State* L) { float x = lua_tonumber(L, 1); float y = lua_tonumber(L, 2); putTriangle(x, y); return 0; } int luafGenerateObject(lua_State* L) { rch::Object* pObj = new rch::Object; pObj->setX(lua_tonumber(L, 1)); pObj->setY(lua_tonumber(L, 2)); apObj.push_back(ObjPtr(pObj)); return 0; } int luafGenObj2(lua_State* L) { rch::Object2* pObj = new rch::Object2; pObj->setX(lua_tonumber(L, 1)); pObj->setY(lua_tonumber(L, 2)); pObj->setFunc(lua_tostring(L, 3)); apObj.push_back(ObjPtr(pObj)); return 0; } int luafGetX(lua_State* L) { rch::Object* pObj = static_cast(lua_touserdata(L, 1)); lua_pushnumber(L, pObj->getX()); return 1; } int luafSetX(lua_State* L) { rch::Object* pObj = static_cast(lua_touserdata(L, 1)); pObj->setX(lua_tonumber(L, 2)); return 0; } int luafGetY(lua_State* L) { rch::Object* pObj = static_cast(lua_touserdata(L, 1)); lua_pushnumber(L, pObj->getY()); return 1; } int luafSetY(lua_State* L) { rch::Object* pObj = static_cast(lua_touserdata(L, 1)); pObj->setY(lua_tonumber(L, 2)); return 0; } int luafGetLocalTime(lua_State* L) { rch::Object* pObj = static_cast(lua_touserdata(L, 1)); lua_pushnumber(L, pObj->getTime()); return 1; } void registerLuaFunctions() { lua_register(L, "cPutTriangle", luafPutTriangle); lua_register(L, "cGenObj", luafGenerateObject); lua_register(L, "cGenObj2", luafGenObj2); lua_register(L, "cGetX", luafGetX); lua_register(L, "cSetX", luafSetX); lua_register(L, "cGetY", luafGetY); lua_register(L, "cSetY", luafSetY); lua_register(L, "cGetLocalTime", luafGetLocalTime); } //********************************************************** LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: try { gl.init(hWnd); } catch (exception& e) { MessageBox(hWnd, e.what(), "例外", MB_OK | MB_ICONERROR); return -1; } return 0; case WM_DESTROY: gl.cleanup(); PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, msg, wp, lp); } } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) { // Lua初期化 L = lua_open(); lua_dofile(L, "main.lua"); luaopen_math(L); // 関数の登録 registerLuaFunctions(); // フレームウィンドウクラスの登録 WNDCLASSEX wc; wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = "Lua - test03"; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wc)) { MessageBox(NULL, "起動できません", "エラー", MB_OK | MB_ICONERROR); return 0; } // フレームウィンドウの作成 g_hWnd = CreateWindow("Lua - test03", "Lua x OpenGL", WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInst, NULL); // ウィンドウはできたかな? if (g_hWnd == NULL) { return 0; } ShowWindow(g_hWnd, SW_SHOWNORMAL); UpdateWindow(g_hWnd); // オブジェクトを発生 lua_pushstring(L, "Initialize"); lua_gettable(L, LUA_GLOBALSINDEX); lua_call(L, 0, 0); MSG msg; while (true) { while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, 0, 0)) { return msg.wParam; } TranslateMessage(&msg); DispatchMessage(&msg); } gl.begin(); glClearColor(0.f, 0.f, 1.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // main関数を呼ぶ lua_pushstring(L, "main"); lua_gettable(L, LUA_GLOBALSINDEX); lua_call(L, 0, 0); ObjPtrItr i; for (i = apObj.begin(); i != apObj.end(); ++i) { (*i)->run(); } gl.swapBuffer(); gl.end(); } } //********************************************************** rch::OpenGL::OpenGL() : m_hDC(NULL), m_hRC(NULL) { } rch::OpenGL::~OpenGL() { } void rch::OpenGL::init(HWND hWnd) { m_hWnd = hWnd; m_hDC = GetDC(hWnd); try { setupPixelFormat(m_hDC); m_hRC = wglCreateContext(m_hDC); wglMakeCurrent(m_hDC, m_hRC); glViewport(50, 20, 500, 400); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); wglMakeCurrent(m_hDC, NULL); } catch (exception& e) { ReleaseDC(hWnd, m_hDC); m_hDC = NULL; throw e; } } void rch::OpenGL::setupPixelFormat(HDC hdc) { // MSDNから流用 PIXELFORMATDESCRIPTOR pfd; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER); pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 16; pfd.cRedBits = 5; pfd.cGreenBits = 5; pfd.cBlueBits = 5; pfd.cAlphaBits = 0; pfd.cAccumRedBits = 0; pfd.cAccumGreenBits = 0; pfd.cAccumBlueBits = 0; pfd.cAccumAlphaBits = 0; pfd.cAccumBits = (pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits); pfd.cDepthBits = 16; pfd.cStencilBits = 16; if (!SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd)) { throw exception("SetPixelFormat failed"); } } void rch::OpenGL::swapBuffer() { SwapBuffers(m_hDC); } void rch::OpenGL::cleanup() { if (m_hRC != NULL) { wglDeleteContext(m_hRC); m_hRC = NULL; } if (m_hDC != NULL) { ReleaseDC(m_hWnd, m_hDC); m_hDC = NULL; } m_hWnd = NULL; } void rch::OpenGL::begin() { wglMakeCurrent(m_hDC, m_hRC); } void rch::OpenGL::end() { wglMakeCurrent(m_hDC, NULL); } //********************************************************** rch::Object::Object() : m_X(0.f), m_Y(0.f), m_Time(0.f) { } rch::Object::~Object() { } void rch::Object::setPos(float x, float y) { setX(x); setY(y); } void rch::Object::setX(float x) { m_X = x; } void rch::Object::setY(float y) { m_Y = y; } void rch::Object::setTime(float t) { m_Time = t; } void rch::Object::incTime(float dt) { setTime(getTime() + dt); } void rch::Object::run() { putTriangle(getX(), getY()); m_Time += 1; } //********************************************************** rch::Object2::Object2() : Object() { } rch::Object2::~Object2() { } void rch::Object2::setFunc(const std::string& sFuncName) { m_sFuncName = sFuncName; } void rch::Object2::run() { putTriangle(getX(), getY()); m_Time += 1; lua_pushstring(L, getFunc().c_str()); lua_gettable(L, LUA_GLOBALSINDEX); lua_pushlightuserdata(L, this); lua_call(L, 1, 0); }