diff options
Diffstat (limited to 'src/libjin-lua/modules/graphics/l_graphics.cpp')
-rw-r--r-- | src/libjin-lua/modules/graphics/l_graphics.cpp | 1112 |
1 files changed, 1112 insertions, 0 deletions
diff --git a/src/libjin-lua/modules/graphics/l_graphics.cpp b/src/libjin-lua/modules/graphics/l_graphics.cpp new file mode 100644 index 0000000..950554a --- /dev/null +++ b/src/libjin-lua/modules/graphics/l_graphics.cpp @@ -0,0 +1,1112 @@ +#include <iostream> +#include <fstream> + +#include "libjin/jin.h" +#include "common/l_object.h" +#include "common/l_common.h" + +#include "l_canvas.h" +#include "l_sprite.h" +#include "l_spritesheet.h" +#include "l_bitmap.h" +#include "l_mesh.h" +#include "l_ttf.h" +#include "l_ttf_data.h" +#include "l_texture.h" +#include "l_shader.h" +#include "l_text.h" +#include "l_texture_font.h" +#include "l_page.h" +#include "l_sprite.h" +#include "l_animation.h" +#include "l_animator.h" +#include "l_particle_system.h" + +using namespace std; +using namespace JinEngine; +using namespace JinEngine::Math; +using namespace JinEngine::Graphics; +using namespace JinEngine::Graphics::Fonts; +using namespace JinEngine::Graphics::Shaders; +using namespace JinEngine::Graphics::Animations; +using namespace JinEngine::Graphics::Particles; +using namespace JinEngine::Filesystem; + +namespace JinEngine +{ + namespace Lua + { + + #include "../../resources/font.ttf.h" + + static struct + { + Color curRenderColor; + Color curClearColor; + Font* defaultFont = nullptr; + bool initialized = false; + } context; + + LUA_IMPLEMENT int l_init(lua_State* L) + { + if (context.initialized) + { + luax_pushboolean(L, true); + return 1; + } + + Window* wnd = Window::get(); + Window::Setting setting; + setting.width = luax_getfieldinteger(L, 1, "width"); + setting.height = luax_getfieldinteger(L, 1, "height"); + setting.title = luax_getfieldstring(L, 1, "title"); + setting.icon = luax_getfieldstring(L, 1, "icon"); + setting.vsync = luax_getfieldbool(L, 1, "vsync"); + setting.fullscreen = luax_getfieldbool(L, 1, "fullscreen"); + setting.resizable = luax_getfieldbool(L, 1, "resizable"); + context.initialized = wnd->start(&setting); + if (!context.initialized) + { + luax_pushboolean(L, context.initialized); + return 1; + } + + /* load default font */ + Bitmap* bitmap = new Bitmap(default_font_bitmap, sizeof(default_font_bitmap)); + TextureFont* tf = new TextureFont(bitmap, Text(Encode::UTF8, default_charset), default_font_split, bitmap->getHeight()); + delete bitmap; + context.defaultFont = tf; + gl.setFont(tf); + + luax_pushboolean(L, context.initialized); + return 1; + } + + LUA_IMPLEMENT int l_setTitle(lua_State* L) + { + Window* wnd = Window::get(); + const char* title = luax_checkstring(L, 1); + wnd->setTitle(title); + return 0; + } + + LUA_IMPLEMENT int l_destroy(lua_State* L) + { + Window* wnd = Window::get(); + wnd->quit(); + return 0; + } + + LUA_IMPLEMENT int l_showWindow(lua_State* L) + { + Window* wnd = Window::get(); + wnd->show(); + return 0; + } + + LUA_IMPLEMENT int l_hideWindow(lua_State* L) + { + Window* wnd = Window::get(); + wnd->hide(); + return 0; + } + + LUA_IMPLEMENT int l_getSize(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + luax_pushnumber(L, wnd->getH()); + return 2; + } + + LUA_IMPLEMENT int l_getWidth(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + return 1; + } + + LUA_IMPLEMENT int l_getHeight(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getH()); + return 1; + } + + LUA_IMPLEMENT int l_newBitmap(lua_State* L) + { + Bitmap* bitmap = nullptr; + if (luax_gettop(L) == 2) + { + int w = luax_checkinteger(L, 1); + int h = luax_checkinteger(L, 2); + bitmap = new Bitmap(w, h); + } + else if (luax_gettop(L) == 3) + { + int w = luax_checkinteger(L, 1); + int h = luax_checkinteger(L, 2); + if (luax_istable(L, 3)) + { + unsigned int r = luax_rawgetnumber(L, 3, 1); + unsigned int g = luax_rawgetnumber(L, 3, 2); + unsigned int b = luax_rawgetnumber(L, 3, 3); + unsigned int a = luax_rawgetnumber(L, 3, 4); + bitmap = new Bitmap(w, h, Color(r, g, b, a)); + } + else if (luax_isfunction(L, 3)) + { + std::function<Color(int, int, int, int)> drawer = [=](int w, int h, int x, int y)->Color{ + luax_pushvalue(L, 3); + luax_pushnumber(L, w); + luax_pushnumber(L, h); + luax_pushnumber(L, x); + luax_pushnumber(L, y); + // Call drawer function. + luax_call(L, 4, 1); + // Get result color. + if (!luax_istable(L, -1)) + luax_error(L, "Return value of bitmap drawer is wrong, should be a color table."); + Color c; + c.r = luax_rawgetnumberthenpop(L, -1, 1); + c.g = luax_rawgetnumberthenpop(L, -1, 2); + c.b = luax_rawgetnumberthenpop(L, -1, 3); + c.a = luax_rawgetnumberthenpop(L, -1, 4); + // Pop return value. + luax_pop(L, 1); + return c; + }; + bitmap = new Bitmap(w, h, drawer); + } + else + { + luax_typerror(L, 3, "color table or color setter"); + return 1; + } + } + else + { + const char* f = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + Buffer b; + try + { + if (!fs->exists(f)) + throw Exception("No such image file %s.", f); + fs->read(f, b); + } + catch (Exception& e) + { + luax_errorf(L, "Failed to read image %s", f); + luax_pushnil(L); + return 1; + } + bitmap = new Bitmap(&b, b.size()); + if (bitmap == nullptr) + { + luax_errorf(L, "Failed to decode image file %s", f); + luax_pushnil(L); + return 1; + } + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Bitmap, new Shared(bitmap)); + return 1; + } + + /* jin.graphics.newTexture(bitmap) */ + LUA_IMPLEMENT int l_newTexture(lua_State* L) + { + Texture* texture = nullptr; + if (luax_istype(L, 1, Jin_Lua_Bitmap)) + { + LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Bitmap); + Bitmap* bitmap = luaObj->getObject<Bitmap>(); + texture = new Texture(bitmap); + } + else if (luax_isstring(L, 1)) + { + const char* path = luax_checkstring(L, 1); + texture = new Texture(path); + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Texture, new Shared(texture)); + return 1; + } + + // See embed graphics.lua. + LUA_IMPLEMENT int l_newShader(lua_State* L) + { + const char* program = luax_checkstring(L, 1); + Shader* jsl = nullptr; + try + { + jsl = new Shader(program); + } + catch (JinEngine::Exception& e) + { + //luax_errorf(L, "Failed to compile shader"); + luax_pushnil(L); + return 1; + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Shader, new Shared(jsl)); + return 1; + } + + // See embed graphics.lua + LUA_IMPLEMENT int l_newShaderf(lua_State* L) + { + const char* path = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + if (!fs->exists(path)) + { + //luax_errorf(L, "No such shader file \"%s\"", path); + luax_pushnil(L); + return 1; + } + Buffer b; + fs->read(path, b); + Shader* jsl = nullptr; + try + { + jsl = new Shader((char*)&b); + } + catch (JinEngine::Exception& e) + { + //luax_errorf(L, "Failed to compile shader"); + luax_pushnil(L); + return 1; + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Shader, new Shared(jsl)); + return 1; + } + + LUA_IMPLEMENT int l_newCanvas(lua_State* L) + { + int w = luax_checknumber(L, 1); + int h = luax_checknumber(L, 2); + Canvas* cvs = new Canvas(w, h); + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Canvas, new Shared(cvs)); + return 1; + } + + LUA_IMPLEMENT int l_clear(lua_State* L) + { + glClear(GL_COLOR_BUFFER_BIT); + return 0; + } + + LUA_IMPLEMENT int l_setClearColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glClearColor(0, 0, 0, 1); + return 0; + } + + context.curClearColor.r = luax_checknumber(L, 1); + context.curClearColor.g = luax_checknumber(L, 2); + context.curClearColor.b = luax_checknumber(L, 3); + context.curClearColor.a = luax_checknumber(L, 4); + + gl.setClearColor(context.curClearColor.r, + context.curClearColor.g, + context.curClearColor.b, + context.curClearColor.a); + return 0; + } + + LUA_IMPLEMENT int l_present(lua_State* L) + { + Window::get()->present(); + return 0; + } + + LUA_IMPLEMENT void l_draw_texture(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Texture)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + float ox = luax_optnumber(L, 7, 0); + float oy = luax_optnumber(L, 8, 0); + LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1); + Texture* tex = luaObj->getObject<Texture>(); + tex->render(x, y, sx, sy, r, ox, oy); + } + + LUA_IMPLEMENT void l_draw_canvas(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Canvas)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + float ox = luax_optnumber(L, 7, 0); + float oy = luax_optnumber(L, 8, 0); + LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1); + Canvas* canvas = luaObj->getObject<Canvas>(); + canvas->render(x, y, sx, sy, r, ox, oy); + } + + /* jin.graphics.draw(text, font, x, y) */ + LUA_IMPLEMENT void l_draw_text(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Text)) + return; + LuaObject* p = (LuaObject*)luax_toudata(L, 1); + Text* text = p->getObject<Text>(); + int x = luax_optnumber(L, 3, 0); + int y = luax_optnumber(L, 4, 0); + int spacing = luax_optnumber(L, 6, 0); + Font* font = nullptr; + LuaObject* p2 = (LuaObject*)luax_toudata(L, 2); + if (luax_istype(L, 2, Jin_Lua_TextureFont)) + { + TextureFont* tf = p2->getObject<TextureFont>(); + font = tf; + } + else if (luax_istype(L, 2, Jin_Lua_TTF)) + { + TTF* ttf = p2->getObject<TTF>(); + font = ttf; + } + else + { + font = context.defaultFont; + } + int lineheight = luax_optnumber(L, 5, font->getFontSize()); + font->render(*text, x, y, lineheight, spacing); + } + + /* jin.graphics.draw(page, x, y) */ + LUA_IMPLEMENT void l_draw_page(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Page)) + return; + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + LuaObject* p = (LuaObject*)luax_toudata(L, 1); + Page* page = p->getObject<Page>(); + Font* font = page->font; + font->render(page, x, y); + } + + LUA_IMPLEMENT void l_draw_sprite(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Sprite)) + return; + LuaObject* luaSprite = (LuaObject*)luax_toudata(L, 1); + Sprite* sprite = luaSprite->getObject<Sprite>(); + float x = luax_checknumber(L, 2); + float y = luax_checknumber(L, 3); + float sx = luax_checknumber(L, 4); + float sy = luax_checknumber(L, 5); + float r = luax_checknumber(L, 6); + sprite->render(x, y, sx, sy, r); + } + + LUA_IMPLEMENT void l_draw_mesh(lua_State* L) + { + if (!luax_istype(L, 1, Jin_Lua_Mesh)) + return; + LuaObject* obj= (LuaObject*)luax_toudata(L, 1); + Mesh* mesh = obj->getObject<Mesh>(); + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + float sx = luax_optnumber(L, 4, 1); + float sy = luax_optnumber(L, 5, 1); + float r = luax_optnumber(L, 6, 0); + float ox = luax_optnumber(L, 7, 0); + float oy = luax_optnumber(L, 8, 0); + mesh->render(x, y, sx, sy, r, ox, oy); + } + + LUA_IMPLEMENT int l_draw(lua_State* L) + { + if (luax_istype(L, 1, Jin_Lua_Texture)) + l_draw_texture(L); + else if (luax_istype(L, 1, Jin_Lua_Canvas)) + l_draw_canvas(L); + else if (luax_istype(L, 1, Jin_Lua_Text)) + l_draw_text(L); + else if (luax_istype(L, 1, Jin_Lua_Page)) + l_draw_page(L); + else if (luax_istype(L, 1, Jin_Lua_Sprite)) + l_draw_sprite(L); + else if (luax_istype(L, 1, Jin_Lua_Mesh)) + l_draw_mesh(L); + else + { + luax_typerror(L, 1, "texture or canvas"); + return 1; + } + return 0; + } + + // draw(tex, quad, x, y, sx, sy, r, ax, ay) + LUA_IMPLEMENT int l_drawq(lua_State* L) + { + if (!luax_istable(L, 2)) + { + luax_typerror(L, 2, "table"); + return 1; + } + Math::Quad q; + q.x = luax_rawgetnumber(L, 2, 1); + q.y = luax_rawgetnumber(L, 2, 2); + q.w = luax_rawgetnumber(L, 2, 3); + q.h = luax_rawgetnumber(L, 2, 4); + luax_pop(L, 4); + int x = luax_optnumber(L, 3, 0); + int y = luax_optnumber(L, 4, 0); + float sx = luax_optnumber(L, 5, 1); + float sy = luax_optnumber(L, 6, 1); + float r = luax_optnumber(L, 7, 0); + float ox = luax_optnumber(L, 8, 0); + float oy = luax_optnumber(L, 9, 0); + + if (luax_istype(L, 1, Jin_Lua_Texture)) + { + LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1); + Texture* tex = luaObj->getObject<Texture>(); + tex->render(q, x, y, sx, sy, r, ox, oy); + } + else if (luax_istype(L, 1, Jin_Lua_Canvas)) + { + LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1); + Canvas* canvas = luaObj->getObject<Canvas>(); + canvas->render(q, x, y, sx, sy, r, ox, oy); + } + else + { + luax_typerror(L, 1, "texture or canvas"); + return 1; + } + return 0; + } + + /* print(string, x, y, lineheight, spacing) */ + /* need set font */ + LUA_IMPLEMENT int l_print(lua_State* L) + { + Font* font = gl.getFont(); + if (font == nullptr) + return 0; + unsigned length; + const char* str = luax_checklstring(L, 1, &length); + Text text(Encode::UTF8, str, length); + int x = luax_optnumber(L, 2, 0); + int y = luax_optnumber(L, 3, 0); + int lineheight = luax_optnumber(L, 4, font->getFontSize()); + int spacing = luax_optnumber(L, 5, 0); + font->render(text, x, y, lineheight, spacing); + return 0; + } + + LUA_IMPLEMENT int l_setColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + gl.setColor(Color(255, 255, 255, 255)); + return 0; + } + + context.curRenderColor.r = luax_checknumber(L, 1); + context.curRenderColor.g = luax_checknumber(L, 2); + context.curRenderColor.b = luax_checknumber(L, 3); + if (luax_gettop(L) == 4) + context.curRenderColor.a = luax_checknumber(L, 4); + else + context.curRenderColor.a = 255; + gl.setColor(context.curRenderColor); + return 0; + } + + LUA_IMPLEMENT int l_getColor(lua_State * L) + { + luax_pushnumber(L, context.curRenderColor.r); + luax_pushnumber(L, context.curRenderColor.g); + luax_pushnumber(L, context.curRenderColor.b); + luax_pushnumber(L, context.curRenderColor.a); + return 4; + } + + LUA_IMPLEMENT int l_bindCanvas(lua_State* L) + { + if (luax_gettop(L) == 0) + { + // bind to default canvas + gl.unbindCanvas(); + return 0; + } + LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas); + Canvas* canvas = luaObj->getObject<Canvas>(); + gl.bindCanvas(canvas); + return 0; + } + + LUA_IMPLEMENT int l_unbindCanvas(lua_State* L) + { + gl.unbindCanvas(); + return 0; + } + + LUA_IMPLEMENT int l_useShader(lua_State* L) + { + if (luax_gettop(L) == 0) + { + gl.unuseShader(); + return 0; + } + if (luax_istype(L, 1, Jin_Lua_Shader)) + { + LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Shader); + Shader* shader = luaObj->getObject<Shader>(); + gl.useShader(shader); + } + else + { + luax_typerror(L, 1, "JSL shader"); + } + return 0; + } + + LUA_IMPLEMENT int l_setBlendMode(lua_State* L) + { + int mode = luax_checkinteger(L, 1); + gl.setBlendMode(static_cast<OpenGL::BlendMode>(mode)); + return 0; + } + + LUA_IMPLEMENT int l_getBlendMode(lua_State* L) + { + int mode = static_cast<int>(gl.getBlendMode()); + luax_pushinteger(L, mode); + return 1; + } + + LUA_IMPLEMENT int l_point(lua_State* L) + { + int x = luax_checknumber(L, 1); + int y = luax_checknumber(L, 2); + JinEngine::Graphics::point(x, y); + + return 0; + } + + LUA_IMPLEMENT int l_line(lua_State* L) + { + int x1 = luax_checknumber(L, 1); + int y1 = luax_checknumber(L, 2); + int x2 = luax_checknumber(L, 3); + int y2 = luax_checknumber(L, 4); + JinEngine::Graphics::line(x1, y1, x2, y2); + + return 0; + } + + LUA_IMPLEMENT int l_rect(lua_State* L) + { + RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1)); + if (mode != RenderMode::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + int w = luax_checknumber(L, 4); + int h = luax_checknumber(L, 5); + rect(mode, x, y, w, h); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + LUA_IMPLEMENT int l_circle(lua_State* L) + { + RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1)); + if (mode != RenderMode::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + float r = luax_checknumber(L, 4); + circle(mode, x, y, r); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + LUA_IMPLEMENT int l_triangle(lua_State* L) + { + RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1)); + if (mode != RenderMode::NONE) + { + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + + int x2 = luax_checknumber(L, 3); + int y2 = luax_checknumber(L, 4); + + int x3 = luax_checknumber(L, 5); + int y3 = luax_checknumber(L, 6); + + triangle(mode, x, y, x2, y2, x3, y3); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + LUA_IMPLEMENT int l_polygon(lua_State* L) + { + RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1)); + int n = luax_checknumber(L, 2); + if (mode != RenderMode::NONE) + { + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + int tn = luax_tableidxlen(L, 3); + if (tn != n * 2) + { + LUA_IMPLEMENT char* emsg = \ + "number of polygon vertices doesn't match " \ + "provided n, expect %d numbers but get %d"; + luax_error(L, emsg, n * 2, tn); + return 1; + } + float* p = (float*)alloca(2 * n * sizeof(float)); + for (int i = 1; i <= 2 * n; ++i) + p[i - 1] = luax_rawgetnumber(L, 3, i); + polygon(mode, p, n); + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + LUA_IMPLEMENT int l_newTTFData(lua_State* L) + { + TTFData* fd = nullptr; + { + const char* path = luax_checkstring(L, 1); + AssetDatabase* fs = AssetDatabase::get(); + if (!fs->exists(path)) + { + luax_errorf(L, "No such font \"%s\"", path); + luax_pushnil(L); + return 1; + } + Buffer b; + fs->read(path, b); + fd = new TTFData(&b, b.size()); + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_TTFData, new Shared(fd)); + return 1; + } + + /* newText(str[, encode]) */ + LUA_IMPLEMENT int l_newText(lua_State* L) + { + Encode encode = Encode::UTF8; + if (luax_gettop(L) == 2) + { + const char* e = luax_checkstring(L, 2); + if (strcmp(e, "UTF8") == 0) encode = Encode::UTF8; + //else if (strcmp(e, "UTF16") == 0) encode = Encode::UTF16; + else if (strcmp(e, "ASCII") == 0) encode = Encode::ASCII; + else + { + luax_error(L, "wrong text encode %s", e); + return 0; + } + } + unsigned length; + const char* data = luax_checklstring(L, 1, &length); + Text* text = new Text(encode, data, length); + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Text, new Shared(text)); + return 1; + } + + // newSprite(Texture tex, Quad quad, Origin origin) + // newSprite(Texture tex, Quad quad, Number ox, Number oy) + // newSprite(Texture tex, Origin origin) + // newSprite(Texture tex, Number ox, Number oy) + LUA_IMPLEMENT int l_newSprite(lua_State* L) + { + int n = luax_gettop(L); + LuaObject* objGraphic = nullptr; + if (luax_istype(L, 1, Jin_Lua_Texture)) + objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture); + else if (luax_istype(L, 1, Jin_Lua_Canvas)) + objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas); + Graphic* graphic = objGraphic->getObject<Graphic>(); + if (objGraphic != nullptr) + { + if (n == 3 && luax_istable(L, 2)) + { + Quad quad; + quad.x = luax_rawgetnumberthenpop(L, 2, 1); + quad.y = luax_rawgetnumberthenpop(L, 2, 2); + quad.w = luax_rawgetnumberthenpop(L, 2, 3); + quad.h = luax_rawgetnumberthenpop(L, 2, 4); + int o = luax_checkinteger(L, 3); + Origin origin = static_cast<Origin>(o); + LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, quad, origin))); + p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic); + } + else if (n == 4) + { + Quad quad; + quad.x = luax_rawgetnumberthenpop(L, 2, 1); + quad.y = luax_rawgetnumberthenpop(L, 2, 2); + quad.w = luax_rawgetnumberthenpop(L, 2, 3); + quad.h = luax_rawgetnumberthenpop(L, 2, 4); + int ox = luax_checkinteger(L, 3); + int oy = luax_checkinteger(L, 4); + LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, quad, ox, oy))); + p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic); + } + else if (n == 2) + { + int o = luax_checkinteger(L, 2); + Origin origin = static_cast<Origin>(o); + LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, origin))); + p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic); + } + else if (n == 3) + { + int ox = luax_checkinteger(L, 2); + int oy = luax_checkinteger(L, 3); + LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, ox, oy))); + p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic); + } + else + { + luax_error(L, "No matched overloaded functions."); + return 1; + } + } + + return 1; + } + + LUA_IMPLEMENT int l_newSpriteSheet(lua_State* L) + { + LuaObject* objGraphic = nullptr; + if (luax_istype(L, 1, Jin_Lua_Texture)) + objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture); + else if(luax_istype(L, 1, Jin_Lua_Canvas)) + objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas); + if (objGraphic != nullptr) + { + Graphic* graphic = objGraphic->getObject<Graphic>(); + Shared* shrSSheet = new Shared(new SpriteSheet(graphic)); + LuaObject* luaSSheet = luax_newinstance(L, Jin_Lua_SpriteSheet, shrSSheet); + luaSSheet->setDependency((int)SpriteSheetDependency::DEP_GRAPHIC, objGraphic); + return 1; + } + else + return 0; + } + + // newAnimation([frames table, loop, speed]) + LUA_IMPLEMENT int l_newAnimation(lua_State* L) + { + int argc = luax_gettop(L); + Animation* animation = new Animation(); + Shared* shrAnimation = new Shared(animation); + LuaObject* luaAnimation = luax_newinstance(L, Jin_Lua_Animation, shrAnimation); + if (argc >= 3) + { + if (!luax_istable(L, 1)) + { + luax_typerror(L, 1, "frames table"); + return 1; + } + bool loop = luax_checkbool(L, 2); + float speed = luax_checknumber(L, 3); + int n = luax_tableidxlen(L, 1); + for (int i = 1; i <= n; ++i) + { + luax_rawgeti(L, 1, i); + LuaObject* luaSprite = (LuaObject*)luax_checktype(L, -1, Jin_Lua_Sprite); + animation->addFrame(luaSprite->getObject<Sprite>()); + int index = animation->getFrameCount() - 1; + luaAnimation->setDependency((int)AnimationDependency::DEP_SPRITES + index, luaSprite); + } + animation->setLoop(loop); + animation->setSpeed(speed); + } + luax_pushvalue(L, argc + 1); + return 1; + } + + // newAnimator([animation]) + LUA_IMPLEMENT int l_newAnimator(lua_State* L) + { + int argc = luax_gettop(L); + Animator* animator = new Animator(); + Shared* shrAniamtor = new Shared(animator); + if (argc >= 1) + { + LuaObject* animation = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation); + animator->setAnimation(animation->getObject<Animation>()); + LuaObject* luaAnimator = luax_newinstance(L, Jin_Lua_Animator, shrAniamtor); + luaAnimator->setDependency((int)AnimatorDependency::DEP_ANIMATION, animation); + return 1; + } + LuaObject* luaAnimator = luax_newinstance(L, Jin_Lua_Animator, shrAniamtor); + return 1; + } + + /* newTextureFont(bitmap, text, color | cellw, cellh) */ + LUA_IMPLEMENT int l_newTextureFont(lua_State* L) + { + LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Bitmap); + Bitmap* bitmap = p->getObject<Bitmap>(); + Text* text; + if (luax_istype(L, 2, Jin_Lua_Text)) + { + LuaObject* pt = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Text); + text = pt->getObject<Text>(); + } + else if (luax_isstring(L, 2)) + { + unsigned len; + const char* str = luax_checklstring(L, 2, &len); + text = new Text(Encode::UTF8, str, len); + } + else + { + luax_typerror(L, 2, "Text or string"); + return 1; + } + float cellh = luax_checknumber(L, 4); + TextureFont* textureFont = nullptr; + if (luax_istable(L, 3)) + { + unsigned int r = luax_rawgetnumber(L, 3, 1); + unsigned int g = luax_rawgetnumber(L, 3, 2); + unsigned int b = luax_rawgetnumber(L, 3, 3); + unsigned int a = luax_rawgetnumber(L, 3, 4); + textureFont = new TextureFont(bitmap, *text, Color(r, g, b, a), cellh); + } + else if (luax_isnumber(L, 3)) + { + float cellw = luax_checknumber(L, 3); + textureFont = new TextureFont(bitmap, *text, cellw, cellh); + } + else + { + luax_error(L, "bad arguments #3 to 'newTextureFont', need to be table or number"); + return 0; + } + if (luax_isstring(L, 2)) + { + // Delete temporary text. + delete text; + } + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_TextureFont, new Shared(textureFont)); + return 1; + } + + LUA_IMPLEMENT int l_newParticleSystem(lua_State* L) + { + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_ParticleSystem, new Shared(new ParticleSystem())); + return 1; + } + + LUA_IMPLEMENT int l_newMesh(lua_State* L) + { + LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Mesh, new Shared(new Mesh())); + return 1; + } + + /* setFont(font) */ + LUA_IMPLEMENT int l_setFont(lua_State* L) + { + if (luax_istype(L, 1, Jin_Lua_TTF)) + { + LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTF); + TTF* ttf = p->getObject<TTF>(); + gl.setFont(ttf); + } + else if (luax_istype(L, 1, Jin_Lua_TextureFont)) + { + LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TextureFont); + TextureFont* tf = p->getObject<TextureFont>(); + gl.setFont(tf); + } + return 0; + } + + LUA_IMPLEMENT int l_unsetFont(lua_State* L) + { + gl.setFont(context.defaultFont); + return 0; + } + + LUA_IMPLEMENT int l_clearMatrix(lua_State* L) + { + gl.clearMatrix(); + return 0; + } + + LUA_IMPLEMENT int l_pushMatrix(lua_State* L) + { + gl.pushMatrix(); + return 0; + } + + LUA_IMPLEMENT int l_popMatrix(lua_State* L) + { + gl.popMatrix(); + return 0; + } + + LUA_IMPLEMENT int l_scale(lua_State* L) + { + float sx = luax_checknumber(L, 1); + float sy = luax_checknumber(L, 2); + gl.scale(sx, sy); + return 0; + } + + LUA_IMPLEMENT int l_translate(lua_State* L) + { + float x = luax_checknumber(L, 1); + float y = luax_checknumber(L, 2); + gl.translate(x, y); + return 0; + } + + LUA_IMPLEMENT int l_rotate(lua_State* L) + { + float r = luax_checknumber(L, 1); + gl.rotate(r); + return 0; + } + + LUA_IMPLEMENT int l_getStats(lua_State* L) + { + OpenGL::Stats stats = gl.getStats(); + luax_newtable(L); + luax_setfieldinteger(L, "drawCalls", stats.drawCalls); + luax_setfieldinteger(L, "canvasSwitches", stats.canvasSwitches); + luax_setfieldinteger(L, "shaderSwitches", stats.shaderSwitches); + luax_setfieldinteger(L, "fontSwitches", stats.fontSwitches); + luax_setfieldinteger(L, "textures", stats.textures); + luax_setfieldinteger(L, "canvases", stats.canvases); + luax_setfieldinteger(L, "fonts", stats.fonts); + return 1; + } + + LUA_EXPORT int luaopen_graphics(lua_State* L) + { + luaopen_Bitmap(L); + luaopen_Texture(L); + luaopen_Canvas(L); + luaopen_TTFData(L); + luaopen_TTF(L); + luaopen_Text(L); + luaopen_TextureFont(L); + luaopen_Page(L); + luaopen_Shader(L); + luaopen_Sprite(L); + luaopen_SpriteSheet(L); + luaopen_Animation(L); + luaopen_Animator(L); + luaopen_ParticleSystem(L); + luaopen_Mesh(L); + + luaL_Reg methods[] = { + { "getStats", l_getStats }, + /* window */ + { "init", l_init }, + { "setTitle", l_setTitle }, + { "getSize", l_getSize }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "destroy", l_destroy }, + { "hideWindow", l_hideWindow }, + { "showWindow", l_showWindow }, + /* creators */ + { "newBitmap", l_newBitmap }, + { "newTexture", l_newTexture }, + { "newShader", l_newShader }, + { "newShaderf", l_newShaderf }, + { "newCanvas", l_newCanvas }, + { "newTTFData", l_newTTFData }, + { "newText", l_newText }, + { "newTextureFont", l_newTextureFont }, + { "newSprite", l_newSprite }, + { "newSpriteSheet", l_newSpriteSheet }, + { "newAnimation", l_newAnimation }, + { "newAnimator", l_newAnimator }, + { "newParticleSystem", l_newParticleSystem }, + { "newMesh", l_newMesh }, + /* render */ + { "setClearColor", l_setClearColor }, + { "clear", l_clear }, + { "draw", l_draw }, + { "print", l_print }, + { "drawq", l_drawq }, + { "setColor", l_setColor }, + { "getColor", l_getColor }, + { "present", l_present }, + { "setBlendMode", l_setBlendMode }, + { "getBlendMode", l_getBlendMode }, + /* canvas */ + { "bindCanvas", l_bindCanvas }, + { "unbindCanvas", l_unbindCanvas }, + /* shader */ + { "useShader", l_useShader }, + /* shapes */ + { "point", l_point }, + { "line", l_line }, + { "rect", l_rect }, + { "circle", l_circle }, + { "triangle", l_triangle }, + { "polygon", l_polygon }, + /* font */ + { "setFont", l_setFont }, + { "unsetFont", l_unsetFont }, + /* transform */ + { "pushMatrix", l_pushMatrix }, + { "clearMatrix", l_clearMatrix }, + { "popMatrix", l_popMatrix }, + { "translate", l_translate }, + { "rotate", l_rotate }, + { "scale", l_scale }, + { 0, 0 } + }; + // Load whole lib. + luax_newlib(L, methods); + return 1; + } + + } // namespace Lua +} // namespace JinEngine
\ No newline at end of file |