diff options
author | chai <chaifix@163.com> | 2018-08-22 13:58:13 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-08-22 13:58:13 +0800 |
commit | 36621e6be9604517c900adc0d97665e975c2b325 (patch) | |
tree | d3db26c2de6b47aee96f6a24d2595ff80a8869b7 /src/lua/modules/graphics/graphics.cpp | |
parent | 95df5cf921f57bfeac0d819994210dfcc2dcad14 (diff) |
*update
Diffstat (limited to 'src/lua/modules/graphics/graphics.cpp')
-rw-r--r-- | src/lua/modules/graphics/graphics.cpp | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/src/lua/modules/graphics/graphics.cpp b/src/lua/modules/graphics/graphics.cpp new file mode 100644 index 0000000..9c1d404 --- /dev/null +++ b/src/lua/modules/graphics/graphics.cpp @@ -0,0 +1,516 @@ +#include "lua/modules/luax.h" +#include "lua/modules/types.h" +#include "libjin/jin.h" +#include "lua/common/common.h" +#include "lua/modules/embed/graphics.lua.h" + +namespace jin +{ +namespace lua +{ + using namespace jin::graphics; + using jin::filesystem::Filesystem; + using jin::filesystem::Buffer; + + typedef Texture Image; + + static struct + { + color curRenderColor; + color curClearColor; + Font* curFont = nullptr; + Font* defaultFont = nullptr; + } context; + + static int l_init(lua_State* L) + { + Window* wnd = Window::get(); + Window::Setting setting; + setting.width = luax_getfield_integer(L, 1, "width"); + setting.height = luax_getfield_integer(L, 1, "height"); + setting.title = luax_getfield_string(L, 1, "title"); + setting.vsync = luax_getfield_bool(L, 1, "vsync"); + setting.fullscreen = luax_getfield_bool(L, 1, "fullscreen"); + setting.resizable= luax_getfield_bool(L, 1, "resizable"); + if (!wnd->init(&setting)) + { + luax_pushboolean(L, false); + return 1; + } + luax_pushboolean(L, true); + return 1; + } + + static int l_destroy(lua_State* L) + { + Window* wnd = Window::get(); + wnd->quit(); + return 0; + } + + static int l_getSize(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + luax_pushnumber(L, wnd->getH()); + return 2; + } + + static int l_getWidth(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getW()); + return 1; + } + + static int l_getHeight(lua_State* L) + { + Window* wnd = Window::get(); + luax_pushnumber(L, wnd->getH()); + return 1; + } + + static int l_newImage(lua_State* L) + { + Filesystem* fs = Filesystem::get(); + const char* f = luax_checkstring(L, 1); + if (!fs->exists(f)) + { + printf("Error: no such image %s\n", f); + exit(1); + } + Buffer b; + fs->read(f, &b); + + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_IMAGE, sizeof(Proxy)); + Image* img = Image::createTexture(b.data, b.size); + proxy->bind(new Ref<Image>(img, JIN_GRAPHICS_IMAGE)); + return 1; + } + + static int l_newShader(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_SHADER, sizeof(Proxy)); + const char* program = luax_checkstring(L, 1); + JSLProgram* jsl = JSLProgram::createJSLProgram(program); + proxy->bind(new Ref<JSLProgram>(jsl, JIN_GRAPHICS_SHADER)); + return 1; + } + + static int l_newCanvas(lua_State* L) + { + int w = luax_checknumber(L, 1); + int h = luax_checknumber(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_CANVAS, sizeof(Proxy)); + Canvas* cvs = Canvas::createCanvas(w, h); + proxy->bind(new Ref<Canvas>(cvs, JIN_GRAPHICS_CANVAS)); + return 1; + } + + static int l_clear(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glClearColor(0, 0, 0, 1); + } + else + { + int r = luax_checknumber(L, 1); + int g = luax_checknumber(L, 2); + int b = luax_checknumber(L, 3); + int a = luax_checknumber(L, 4); + glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); + } + glClear(GL_COLOR_BUFFER_BIT); + return 0; + } + + static int l_setClearColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glClearColor(1, 1, 1, 1); + return 0; + } + + context.curClearColor.rgba.r = luax_checknumber(L, 1); + context.curClearColor.rgba.g = luax_checknumber(L, 2); + context.curClearColor.rgba.b = luax_checknumber(L, 3); + context.curClearColor.rgba.a = luax_checknumber(L, 4); + + glClearColor(context.curClearColor.rgba.r / 255.f, + context.curClearColor.rgba.g / 255.f, + context.curClearColor.rgba.b / 255.f, + context.curClearColor.rgba.a / 255.f); + return 0; + } + + static int l_present(lua_State* L) + { + Window::get()->swapBuffers(); + return 0; + } + + static int l_draw(lua_State* L) + { + 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); + if (luax_istype(L, 1, JIN_GRAPHICS_IMAGE)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Image>& tex = proxy->getRef<Image>(); + tex->draw(x, y, sx, sy, r); + } + else if (luax_istype(L, 1, JIN_GRAPHICS_CANVAS)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<Canvas>& p = proxy->getRef<Canvas>(); + p->draw(x, y, sx, sy, r); + } + else + { + /* wrong type */ + luax_typerror(L, 1, "image or canvas"); + } + return 0; + } + + static int l_setColor(lua_State* L) + { + if (luax_gettop(L) == 0) + { + glColor4f(1, 1, 1, 1); + return 0; + } + + context.curRenderColor.rgba.r = luax_checknumber(L, 1); + context.curRenderColor.rgba.g = luax_checknumber(L, 2); + context.curRenderColor.rgba.b = luax_checknumber(L, 3); + context.curRenderColor.rgba.a = luax_checknumber(L, 4); + + glColor4f(context.curRenderColor.rgba.r / 255.f, + context.curRenderColor.rgba.g / 255.f, + context.curRenderColor.rgba.b / 255.f, + context.curRenderColor.rgba.a / 255.f); + return 0; + } + + static int l_getColor(lua_State * L) + { + luax_pushnumber(L, context.curRenderColor.rgba.r); + luax_pushnumber(L, context.curRenderColor.rgba.g); + luax_pushnumber(L, context.curRenderColor.rgba.b); + luax_pushnumber(L, context.curRenderColor.rgba.a); + return 4; + } + + static int l_bindCanvas(lua_State* L) + { + if (luax_gettop(L) == 0) + { + // bind to default canvas + Canvas::unbind(); + return 0; + } + Proxy* proxy = (Proxy*)luax_checktype(L, 1, JIN_GRAPHICS_CANVAS); + Ref<Canvas>& ref = proxy->getRef<Canvas>(); + ref->bind(); + return 0; + } + + static int l_unbindCanvas(lua_State* L) + { + Canvas::unbind(); + return 0; + } + + static int l_useShader(lua_State* L) + { + if (luax_gettop(L) == 0) + { + JSLProgram::unuse(); + return 0; + } + if (luax_istype(L, 1, JIN_GRAPHICS_SHADER)) + { + Proxy* proxy = (Proxy*)luax_toudata(L, 1); + Ref<JSLProgram>& jsl = proxy->getRef<JSLProgram>(); + jsl->use(); + } + else + { + luax_typerror(L, 1, "JSL shader"); + } + return 0; + } + + static int l_unuseShader(lua_State* L) + { + JSLProgram::unuse(); + return 0; + } + + static int l_setBlend(lua_State* L) + { + + return 0; + } + + static RENDER_MODE strtomode(const char* str) + { + std::string s = std::string(str); + if (s == "fill") return RENDER_MODE::FILL; + else if (s == "line") return RENDER_MODE::LINE; + else return RENDER_MODE::NONE; + } + + static int l_drawpoint(lua_State* L) + { + int x = luax_checknumber(L, 1); + int y = luax_checknumber(L, 2); + jin::graphics::point(x, y); + + return 0; + } + + static int l_drawLine(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); + jin::graphics::line(x1, y1, x2, y2); + + return 0; + } + + static int l_drawRect(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::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; + } + + static int l_drawCircle(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::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; + } + + static int l_drawTriangle(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::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; + } + + static int l_drawPolygon(lua_State* L) + { + const char* modestr = luax_checkstring(L, 1); + int n = luax_checknumber(L, 2); + RENDER_MODE mode = strtomode(modestr); + if (mode != RENDER_MODE::NONE) + { + if (!luax_istable(L, 3)) + { + luax_typerror(L, 3, "table"); + return 1; + } + int tn = luax_tableidxlen(L, 3); + if (tn != n * 2) + { + static 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 = new float[2 * n]; + for (int i = 1; i <= 2 * n; ++i) + p[i - 1] = luax_rawgetnumber(L, 3, i); + polygon(mode, p, n); + delete[] p; + } + else + { + luax_typerror(L, 1, "'fill' or 'line'"); + return 1; + } + + return 0; + } + + static int l_newFont(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_newinstance(L, JIN_GRAPHICS_FONT, sizeof(Proxy)); + Font* font = new Font(); + { + const char* path = luax_checkstring(L, 1); + Filesystem* fs = Filesystem::get(); + Buffer b = {}; + if (!fs->exists(path)) + { + printf("Error: no such font %s\n", path); + exit(1); + } + fs->read(path, &b); + font->loadb((const unsigned char*)b.data); + } + proxy->bind(new Ref<Font>(font, JIN_GRAPHICS_FONT)); + return 1; + } + + static int l_study(lua_State* L) + { + int n = luax_gettop(L); + if (n == 0) + { + if (context.defaultFont == 0) + { + #include "lua/resources/font.ttf.h" + // load default font + context.defaultFont = new Font(); + context.defaultFont->loadb(font_ttf); + } + context.curFont = context.defaultFont; + return 0; + } + Font* font = (Font*)luax_checktype(L, 1, JIN_GRAPHICS_FONT); + context.curFont = font; + return 0; + } + + static int l_write(lua_State* L) + { + if (context.curFont == 0) + return 0; + + const char* text = luax_checkstring(L, 1); + int x = luax_checknumber(L, 2); + int y = luax_checknumber(L, 3); + + int fh = luax_optnumber(L, 4, 15); + int spacing = luax_optnumber(L, 5, 1); + int lh = luax_optnumber(L, 6, 18); + + context.curFont->render(text, x, y, fh, spacing, lh); + + return 0; + } + + static int l_box(lua_State* L) + { + const char* text = luax_checkstring(L, 1); + int fontheight = luax_checknumber(L, 2); + int spacing = luax_checknumber(L, 3); + int lineheight = luax_checknumber(L, 4); + int w, h; + context.curFont->box(text, fontheight, spacing, lineheight, &w, &h); + luax_pushnumber(L, w); + luax_pushnumber(L, h); + return 2; + } + + static const luaL_Reg f[] = { + { "init", l_init }, + { "getSize", l_getSize }, + { "getWidth", l_getWidth }, + { "getHeight", l_getHeight }, + { "newImage", l_newImage }, + { "newShader", l_newShader }, + { "newCanvas", l_newCanvas }, + { "newFont", l_newFont }, + { "box", l_box }, + { "write", l_write }, + { "setClearColor", l_setClearColor }, + { "clear", l_clear }, + { "draw", l_draw }, + { "setColor", l_setColor }, + { "palette", l_getColor }, + { "present", l_present }, + { "setFont", l_study }, + { "bindCanvas", l_bindCanvas }, + { "unbindCanvas", l_unbindCanvas }, + { "useShader", l_useShader }, + { "unuseShader", l_unuseShader }, + { "point", l_drawpoint }, + { "line", l_drawLine }, + { "rect", l_drawRect }, + { "circle", l_drawCircle }, + { "triangle", l_drawTriangle }, + { "polygon", l_drawPolygon }, + { "destroy", l_destroy }, + { 0, 0 } + }; + + extern int luaopen_Image(lua_State* L); + extern int luaopen_Font(lua_State* L); + extern int luaopen_Canvas(lua_State* L); + extern int luaopen_JSL(lua_State* L); + + int luaopen_graphics(lua_State* L) + { + // register types + luaopen_Image(L); + luaopen_Canvas(L); + luaopen_Font(L); + luaopen_JSL(L); + + // load whole lib + luax_newlib(L, f); + + return 1; + } + +}// lua +}// jin
\ No newline at end of file |