一个简单的基于OpenGL的Lua的游戏引擎的实例

来源:互联网 发布:淘宝产品价格变动 编辑:程序博客网 时间:2024/05/21 10:50

学习了几天Lua,今天突然想为Lua写一个简单的游戏引擎方便使用Lua单独的开发游戏,下面是一个基本的代码(很简单), Lua的代码也测试通过了但还不完整,稍候再发上来

代码如下:

#define PENQ_LUAGAME#include <string.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>#include <lua/lua.h>#include <lua/lauxlib.h>#include <lua/lualib.h>#include "FreeImage.h"enum {LGME_MOVE = 0x00000001, LGME_DOWN = 0x00000002,LGME_DOWNMOVE = 0x00000004,LGME_UP = 0x00000008,LGME_ENTRY = 0x00000010,LGME_LEAVE = 0x00000020};struct LGMain{lua_State *L;GLintw;GLinth;GLfloatzoom;GLuintmouse_event;GLuintkey_event;}G_Main = {NULL,0, 0, 0.0f, 0, 0};struct LGImage{GLintwidth;GLintheight;GLuint texture;GLinthas_alpha_channel;};typedef struct LGImage LGImage;typedef struct {intw;int h;unsigned char*buf;GLinthas_alpha_channel;}GLBITMAP;GLBITMAP * FIBitmap2GLBitmap(FIBITMAP *fibmp){int i, j, k;int pitch = FreeImage_GetPitch(fibmp);unsigned char *bits = FreeImage_GetBits(fibmp);int bpp = FreeImage_GetBPP(fibmp);GLBITMAP *glbmp = (GLBITMAP *)malloc(sizeof(GLBITMAP));RGBQUAD *palette = NULL;if ( !glbmp ) return NULL;glbmp->has_alpha_channel = 0;glbmp->w = FreeImage_GetWidth(fibmp);glbmp->h = FreeImage_GetHeight(fibmp);switch ( bpp ) {case 8:if ( !(palette = FreeImage_GetPalette(fibmp)) ) return NULL; if ( !(glbmp->buf = (unsigned char *)malloc(glbmp->w*glbmp->h*3)) ) return NULL;for ( i = 0; i < glbmp->h; ++i ) {for ( j = 0; j < glbmp->w; ++j ) {k = bits[i*pitch+j];glbmp->buf[(i*glbmp->w+j)*3+0] = palette[k].rgbRed;glbmp->buf[(i*glbmp->w+j)*3+1] = palette[k].rgbGreen;glbmp->buf[(i*glbmp->w+j)*3+2] = palette[k].rgbBlue;}}break;case 24:if ( !(glbmp->buf = (unsigned char *)malloc(glbmp->w*glbmp->h*3)) ) return NULL;for ( i = 0; i < glbmp->h; ++i ) {for ( j = 0; j < glbmp->w; ++j ) {glbmp->buf[(i*glbmp->w+j)*3+0] = bits[i*pitch+j*3+2];glbmp->buf[(i*glbmp->w+j)*3+1] = bits[i*pitch+j*3+1];glbmp->buf[(i*glbmp->w+j)*3+2] = bits[i*pitch+j*3+0];}}break;case 32:if ( !(glbmp->buf = (unsigned char *)malloc(glbmp->w*glbmp->h*4)) ) return NULL;glbmp->has_alpha_channel = 1;for ( i = 0; i < glbmp->h; ++i ) {for ( j = 0; j < glbmp->w; ++j ) {glbmp->buf[(i*glbmp->w+j)*4+0] = bits[i*pitch+j*4+2];glbmp->buf[(i*glbmp->w+j)*4+1] = bits[i*pitch+j*4+1];glbmp->buf[(i*glbmp->w+j)*4+2] = bits[i*pitch+j*4+0];glbmp->buf[(i*glbmp->w+j)*4+3] = bits[i*pitch+j*4+3];}}break;default: return NULL;}return glbmp;}void FreeGLBitmap(GLBITMAP *glbmp){if ( glbmp ) {if ( glbmp->buf ) free(glbmp->buf);free(glbmp);}}LGImage * LoadLGImage(const char *filename){FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;FIBITMAP *bitmap = NULL;GLBITMAP *glbmp = NULL;LGImage *image = NULL;fif = FreeImage_GetFileType(filename, 0);if ( FIF_UNKNOWN == fif ) {fif = FreeImage_GetFIFFromFilename(filename);if ( FIF_UNKNOWN == fif )return 0;}if ( FreeImage_FIFSupportsReading(fif) ) bitmap = FreeImage_Load(fif, filename, 0);if ( !bitmap ) return 0;if ( !(glbmp = FIBitmap2GLBitmap(bitmap)) ) {FreeImage_Unload(bitmap);return 0;}if ( !(image = (LGImage *)malloc(sizeof(LGImage))) ) {FreeGLBitmap(glbmp);FreeImage_Unload(bitmap);return 0;}image->width = glbmp->w;image->height = glbmp->h;image->has_alpha_channel = glbmp->has_alpha_channel;glGenTextures(1, &image->texture);glBindTexture(GL_TEXTURE_2D, image->texture);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);if ( glbmp->has_alpha_channel )glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glbmp->w, glbmp->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, glbmp->buf);elseglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glbmp->w, glbmp->h, 0, GL_RGB, GL_UNSIGNED_BYTE, glbmp->buf);FreeGLBitmap(glbmp);FreeImage_Unload(bitmap);return image;}static void init_gl(){glShadeModel(GL_SMOOTH);glClearColor(0.0f, 0.0f, 0.0f, 0.0f);glClearDepth(1.0f);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);}static void reshape(GLint w, GLint h){if ( 0 == h ) h = 1;G_Main.w = w;G_Main.h = h;G_Main.zoom = (GLfloat)(w > h ? h : w);glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0f, (GLfloat)w/(GLfloat)h, 0.1f, G_Main.zoom);glMatrixMode(GL_MODELVIEW);glLoadIdentity();if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_Reshape");lua_pushnumber(G_Main.L, w);lua_pushnumber(G_Main.L, h);lua_pcall(G_Main.L, 2, 0, 0);}}static void display(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(-(GLfloat)(G_Main.w>>1), -(GLfloat)(G_Main.h>>1), -G_Main.zoom);if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_Display");lua_pcall(G_Main.L, 0, 0, 0);}glutSwapBuffers();}static void mouse(int button, int state, int x, int y){if ( GLUT_DOWN == state ) {if ( G_Main.mouse_event & LGME_DOWN ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseDown");lua_pushnumber(G_Main.L, button);lua_pushnumber(G_Main.L, x);lua_pushnumber(G_Main.L, y);lua_pcall(G_Main.L, 3, 0, 0);}}} else if ( GLUT_UP == state ) {if ( G_Main.mouse_event & LGME_UP ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseUp");lua_pushnumber(G_Main.L, button);lua_pushnumber(G_Main.L, x);lua_pushnumber(G_Main.L, y);lua_pcall(G_Main.L, 3, 0, 0);}}}}static void mouse_move(int x, int y){if ( G_Main.mouse_event & LGME_MOVE ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseMove");lua_pushnumber(G_Main.L, x);lua_pushnumber(G_Main.L, y);lua_pcall(G_Main.L, 2, 0, 0);}}}static void mouse_down_move(int x, int y){if ( G_Main.mouse_event & LGME_DOWNMOVE ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseDownMove");lua_pushnumber(G_Main.L, x);lua_pushnumber(G_Main.L, y);lua_pcall(G_Main.L, 2, 0, 0);}}}static void mouse_foucs(int state){if ( GLUT_LEFT == state ) {if ( G_Main.mouse_event & LGME_LEAVE ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseLeave");lua_pcall(G_Main.L, 0, 0, 0);}}} else if ( GLUT_ENTERED == state ) {if ( G_Main.mouse_event & LGME_ENTRY ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_MouseEntry");lua_pcall(G_Main.L, 0, 0, 0);}}}}static void keyboard(unsigned char key, int x, int y){if ( G_Main.key_event ) {if ( G_Main.L ) {lua_getglobal(G_Main.L, "LuaGame_Keyboard");lua_pushnumber(G_Main.L, key);lua_pushnumber(G_Main.L, x);lua_pushnumber(G_Main.L, y);lua_pcall(G_Main.L, 3, 0, 0);}}}/*$@@ 引擎初始化$@ 返回值: 成功true, 否则false*/static int LuaGame_Init(lua_State *L){int argc = 1;char *argv[1] = {"LuaGame"};#if defined(FREEIMAGE_LIB)FreeImage_Initialise(0);#endifglutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);lua_pushboolean(L, 1);return 1;}/*$@@ 创建窗体(5个参数)$@ 第一个参数: 窗体名$@ 第二个参数: 窗体初始位置的x坐标$@ 第三个参数: 窗体初始位置的y坐标$@ 第四个参数: 窗体的宽$@ 第五个参数: 窗体的高$@ 返回值: 成功true, 否则false*/static int LuaGame_CreateWindow(lua_State *L){const char *caption = luaL_checkstring(L, 1);int x = luaL_checknumber(L, 2);int y = luaL_checknumber(L, 3);int w = luaL_checknumber(L, 4);int h = luaL_checknumber(L, 5);glutInitWindowPosition(x, y);glutInitWindowSize(w, h);if ( glutCreateWindow(caption) ) {init_gl();glutMouseFunc(mouse);glutMotionFunc(mouse_down_move);glutPassiveMotionFunc(mouse_move);glutEntryFunc(mouse_foucs);glutKeyboardFunc(keyboard);glutReshapeFunc(reshape);glutDisplayFunc(display);glutIdleFunc(display);lua_pushboolean(L, 1);} elselua_pushboolean(L, 0);return 1;}/*$@@ 开启鼠标移动监听事件*/static int LuaGame_SetMouseMove(lua_State *L){G_Main.mouse_event |= LGME_MOVE;return 0;}/*$@@ 开启鼠标按下监听事件*/static int LuaGame_SetMouseDown(lua_State *L){G_Main.mouse_event |= LGME_DOWN;return 0;}/*$@@ 开启鼠标按下时移动监听事件*/static int LuaGame_SetMouseDownMove(lua_State *L){G_Main.mouse_event |= LGME_DOWNMOVE;return 0;}/*$@@ 开启鼠标弹起监听事件*/static int LuaGame_SetMouseUp(lua_State *L){G_Main.mouse_event |= LGME_UP;return 0;}/*$@@ 开启鼠标进入监听事件*/static int LuaGame_SetMouseEntry(lua_State *L){G_Main.mouse_event |= LGME_ENTRY;return 0;}/*$@@ 开启鼠标离开监听事件*/static int LuaGame_SetMouseLeave(lua_State *L){G_Main.mouse_event |= LGME_LEAVE;return 0;}/*$@@ 设置键盘监听事件*/static int LuaGame_SetKeyboard(lua_State *L){G_Main.key_event = 1;return 0;}static int LuaGame_CreateImage(lua_State *L){const char *filename = luaL_checkstring(L, 1);LGImage *image = NULL;if ( filename ) {if ( (image = LoadLGImage(filename)) ) {lua_pushboolean(L, 1);lua_pushlightuserdata(L, image);return 2;}}lua_pushboolean(L, 0);lua_pushlightuserdata(L, NULL);return 2;}static int LuaGame_GetImageWidth(lua_State *L){LGImage *image = lua_touserdata(L, 1);image ? lua_pushnumber(L, image->width) : lua_pushnil(L);return 1;}static int LuaGame_GetImageHeight(lua_State *L){LGImage *image = lua_touserdata(L, 1);image ? lua_pushnumber(L, image->height) : lua_pushnil(L);return 1;}static int LuaGame_RenderImage(lua_State *L){LGImage *image = (LGImage *)lua_touserdata(L, 1);GLint x = (GLint)luaL_checknumber(L, 2);GLint y = (GLint)luaL_checknumber(L, 3);if ( image ) {glEnable(GL_TEXTURE_2D);if ( image->has_alpha_channel ) {glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glDisable(GL_DEPTH_TEST);} else {glDisable(GL_BLEND);glEnable(GL_DEPTH_TEST);}glBindTexture(GL_TEXTURE_2D, image->texture);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3d(x, y-image->height, 0);glTexCoord2f(1.0f, 0.0f); glVertex3d(x+image->width, y-image->height, 0);glTexCoord2f(1.0f, 1.0f); glVertex3d(x+image->width, y, 0);glTexCoord2f(0.0f, 1.0f); glVertex3d(x, y, 0);glEnd();if ( image->has_alpha_channel ) {glDisable(GL_BLEND);glEnable(GL_DEPTH_TEST);}glDisable(GL_TEXTURE_2D);}return 0;}static int LuaGame_Release(lua_State *L){return 0;}static int LuaGame_Start(lua_State *L){glutMainLoop();#if defined(FREEIMAGE_LIB)FreeImage_DeInitialise();#endifreturn 0;}/*$@@ 动态库导出函数(格式: luaopen_+库名)*/#define LUAGAME_REGFUNC(l, f)lua_register(l, #f, f)int luaopen_LuaGame(lua_State *L){G_Main.L = L;LUAGAME_REGFUNC(L, LuaGame_Init);LUAGAME_REGFUNC(L, LuaGame_CreateWindow);LUAGAME_REGFUNC(L, LuaGame_SetMouseMove);LUAGAME_REGFUNC(L, LuaGame_SetMouseDown);LUAGAME_REGFUNC(L, LuaGame_SetMouseDownMove);LUAGAME_REGFUNC(L, LuaGame_SetMouseUp);LUAGAME_REGFUNC(L, LuaGame_SetMouseEntry);LUAGAME_REGFUNC(L, LuaGame_SetMouseLeave);LUAGAME_REGFUNC(L, LuaGame_SetKeyboard);LUAGAME_REGFUNC(L, LuaGame_CreateImage);LUAGAME_REGFUNC(L, LuaGame_GetImageWidth);LUAGAME_REGFUNC(L, LuaGame_GetImageHeight);LUAGAME_REGFUNC(L, LuaGame_RenderImage);LUAGAME_REGFUNC(L, LuaGame_Start);LUAGAME_REGFUNC(L, LuaGame_Release);return 0;}



原创粉丝点击