diff options
-rw-r--r-- | Makefile | 41 | ||||
-rw-r--r-- | src/plugin-luaosmesa.cc | 254 |
2 files changed, 280 insertions, 15 deletions
@@ -20,9 +20,9 @@ CPPFLAGS += $(INCLUDES) -O4 -fexceptions -DSTDC_HEADERS -DREADLINE_STATIC -DHOOK LDFLAGS += -O4 -fexceptions -shared -fPIC -L/usr/lib/oracle/11.1.0.1/client/lib -vpath %.c ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../paperIdol/src:../mogltk/lib:../tinyxml -vpath %.cc ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../paperIdol/src:../mogltk/lib:../tinyxml -vpath %.cpp ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../paperIdol/src:../mogltk/lib:../tinyxml +vpath %.c ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../mogltk/lib:../tinyxml +vpath %.cc ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../mogltk/lib:../tinyxml +vpath %.cpp ../Baltisot/lib:../Baltisot/src:../Baltisot/lib/zlib/src:../Baltisot/lib/lua/src:../Baltisot/lib/lua/src/LuaLib:src:../mogltk/lib:../tinyxml vpath %.lua ../Baltisot/lib:../Baltisot/src CONFIGFILES_SOURCES = \ @@ -92,7 +92,7 @@ GL_SOURCES = \ plugin-luagl.cc \ LuaGL.cc \ -GL_LIBS = ../Mesa-7.0.2/lib/libGLU.a ../Mesa-7.0.2/lib/libOSMesa.a +GL_LIBS = FTGL_SOURCES = \ plugin-luaftgl.cc \ @@ -100,6 +100,12 @@ LuaFTGL.cc \ FTGL_LIBS = -lfreetype -lftgl +OSMESA_SOURCES = \ +plugin-luaosmesa.cc \ +dds.c + +OSMESA_LIBS = `Magick++-config --libs` + WHOLE_SOURCES = \ $(CONFIGFILES_SOURCES) \ $(XML_SOURCES) \ @@ -112,6 +118,7 @@ $(SQL_SOURCES) \ $(LUALIBS_SOURCES) \ $(GL_SOURCES) \ $(FTGL_SOURCES) \ +$(OSMESA_SOURCES) \ MODULES_LIST = \ luaconfigfiles.so \ @@ -125,6 +132,7 @@ luasql.so \ luagl.so \ luaftgl.so \ lualibs.so \ +luaosmesa.so \ ALL_OBJECTS = $(addsuffix .o, $(notdir $(basename $(WHOLE_SOURCES) $(LUA_LIB)))) ALL_DEPS = $(addsuffix .dep, $(notdir $(basename $(WHOLE_SOURCES)))) @@ -136,37 +144,40 @@ modules: $(MODULES_LIST) dep: $(ALL_DEPS) luaconfigfiles.so: $(addsuffix .o, $(notdir $(basename $(CONFIGFILES_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(CONFIGFILES_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(CONFIGFILES_LIBS) luaxml.so: $(addsuffix .o, $(notdir $(basename $(XML_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(XML_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(XML_LIBS) luaocci.so: $(addsuffix .o, $(notdir $(basename $(OCCI_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(OCCI_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(OCCI_LIBS) luahandle.so: $(addsuffix .o, $(notdir $(basename $(HANDLE_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(HANDLE_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(HANDLE_LIBS) luahttp.so: $(addsuffix .o, $(notdir $(basename $(HTTP_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(HTTP_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(HTTP_LIBS) luaregex.so: $(addsuffix .o, $(notdir $(basename $(REGEX_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(REGEX_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(REGEX_LIBS) luatask.so: $(addsuffix .o, $(notdir $(basename $(TASK_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(TASK_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(TASK_LIBS) luasql.so: $(addsuffix .o, $(notdir $(basename $(SQL_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(SQL_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(SQL_LIBS) luagl.so: $(addsuffix .o, $(notdir $(basename $(GL_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(GL_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(GL_LIBS) luaftgl.so: $(addsuffix .o, $(notdir $(basename $(FTGL_SOURCES)))) - $(LD) $(LDFLAGS) -o $@ $+ $(FTGL_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(FTGL_LIBS) lualibs.so: $(addsuffix .o, $(notdir $(basename $(LUALIBS_SOURCES) $(LUA_LIB)))) - $(LD) $(LDFLAGS) -o $@ $+ $(LUALIBS_LIBS) + $(LD) $(LDFLAGS) -o $@ $+ $(LUALIBS_LIBS) + +luaosmesa.so: $(addsuffix .o, $(notdir $(basename $(OSMESA_SOURCES)))) + $(LD) $(LDFLAGS) -o $@ $+ $(OSMESA_LIBS) clean: rm -f *.o *.dep *.so diff --git a/src/plugin-luaosmesa.cc b/src/plugin-luaosmesa.cc new file mode 100644 index 0000000..830c2db --- /dev/null +++ b/src/plugin-luaosmesa.cc @@ -0,0 +1,254 @@ +#include <GL/gl.h> +#include <GL/glu.h> +#include <GL/osmesa.h> + +#include <Magick++.h> +#include <string> +#include <iostream> +#include <list> + +#include <dds.h> + +#include <LuaHandle.h> +#include <BLua.h> + +#ifndef WIN32 +#define WEAK __attribute__ ((weak)) +#else +#define WEAK +#endif + +OSMesaContext ctx = 0; +void *buffer = 0; +int width = -1; +int height = -1; +bool upscale = false; + +class scene_t : public Base { + public: + std::list<Magick::Image> scene; + String filename, tmp_filename; +};void empty_scene(scene_t scene) { + while (scene.scene.begin() != scene.scene.end()) { + scene.scene.pop_front(); + } +} + +scene_t * init_OSMesa_context(scene_t * scene, int _width, int _height) { + scene_t * r = scene; + + if ((width > 2048) || (height > 2048)) { + printf("Image too wide!\n"); + return NULL; + } + + if (!r) + r = new scene_t(); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + + if ((width == _width) && (height == _height)) { + return r; + } + + width = _width; + height = _height; + + /* Bind the buffer to the context and make it current */ + if (!OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, width, height)) { + printf("OSMesaMakeCurrent (8 bits/channel) failed!\n"); + delete r; + return NULL; + } + return r; +} + +void init_OSMesa() { + const GLint z = 32, stencil = 0, accum = 0; + + ctx = OSMesaCreateContextExt(OSMESA_BGRA, z, stencil, accum, NULL); + if (!ctx) { + printf("OSMesaCreateContextExt() failed!\n"); + return; + } + + buffer = malloc(2048 * 2048 * 4); + + if (!buffer) { + printf("Alloc image buffer failed!\n"); + return; + } + + delete init_OSMesa_context(0, 300, 300); + glPopAttrib(); +} + +void flip_scene(scene_t * scene, const char * buffer, int width, int height, bool upscale) { + /* Make sure buffered commands are finished! */ + glFinish(); + + Magick::Image i(width, height, "BGRA", Magick::CharPixel, buffer); + i.flip(); + i.animationDelay(6); + i.opacity(0); + + if (upscale) { + i.resize(Magick::Geometry(width / 2, height / 2)); + } + + scene->scene.push_back(i); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void * dump_scene_threaded(void * arg) { + scene_t * scene = (scene_t *) arg; + char fname[2049]; + + writeImages(scene->scene.begin(), scene->scene.end(), scene->tmp_filename.to_charp()); + unlink(scene->filename.to_charp()); + rename(scene->tmp_filename.to_charp(), scene->filename.to_charp()); + delete scene; + pthread_exit(0); +} + +void dump_scene(scene_t * scene, const String & filename, Handle * out, const char * buffer, int width, int height, bool upscale) { + if (scene->scene.begin() == scene->scene.end()) + flip_scene(scene, buffer, width, height, upscale); + + if (out) { + Magick::Blob b; + scene->scene.begin()->magick("JPEG"); + scene->scene.begin()->quality(95); + writeImages(scene->scene.begin(), scene->scene.end(), &b); + out->write(b.data(), b.length()); + delete scene; + } else { + pthread_t thread; + scene->filename = filename; + scene->tmp_filename = "tmp-" + filename; + if (pthread_create(&thread, NULL, dump_scene_threaded, scene) == 0) { + pthread_detach(thread); + } + } + + glPopAttrib(); + + return; +} + +class plugin_osmesa : public Base { +}; + +class Luaplugin_osmesa : public LuaObject { + public: + static void pushstatics(Lua *) throw (GeneralException); + protected: + virtual void pushmembers(Lua *); +}; + +enum plugin_osmesa_functions_t { + PLUGIN_OSMESA_INITOSMESA, + PLUGIN_OSMESA_FLIPSCENE, + PLUGIN_OSMESA_DUMPSCENE, + PLUGIN_OSMESA_LOADTEX, +}; + +struct lua_functypes_t plugin_osmesa_functions[] = { + { PLUGIN_OSMESA_INITOSMESA, "InitOSMesa", 3, 4, { BLUA_USERDATA | BLUA_NIL, BLUA_NUMBER, BLUA_NUMBER, BLUA_BOOLEAN } }, + { PLUGIN_OSMESA_FLIPSCENE, "FlipScene", 1, 1, { BLUA_USERDATA } }, + { PLUGIN_OSMESA_DUMPSCENE, "DumpScene", 2, 2, { BLUA_USERDATA, BLUA_STRING | BLUA_OBJECT } }, + { PLUGIN_OSMESA_LOADTEX, "LoadTex", 1, 1, { BLUA_STRING } }, + { -1, 0, 0, 0, 0 } +}; + +class sLua_plugin_osmesa : public Base { + public: + DECLARE_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_INITOSMESA); + DECLARE_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_FLIPSCENE); + DECLARE_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_DUMPSCENE); + DECLARE_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_LOADTEX); + private: + static int plugin_osmesa_proceed(Lua * L, int n, plugin_osmesa * obj, int caller); + static int plugin_osmesa_proceed_statics(Lua * L, int n, int caller); +}; +void Luaplugin_osmesa::pushmembers(Lua * L) { } + +void Luaplugin_osmesa::pushstatics(Lua * L) throw (GeneralException) { + //CHECK_METHODS(plugin_osmesa); + CHECK_FUNCTIONS(plugin_osmesa); + + PUSH_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_INITOSMESA); + PUSH_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_FLIPSCENE); + PUSH_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_DUMPSCENE); + PUSH_FUNCTION(plugin_osmesa, PLUGIN_OSMESA_LOADTEX); +} + +int sLua_plugin_osmesa::plugin_osmesa_proceed(Lua * L, int n, plugin_osmesa * obj, int caller) { + return 0; +} + +int sLua_plugin_osmesa::plugin_osmesa_proceed_statics(Lua * L, int n, int caller) { + int _width, _height, r = 0; + String filename; + const char * t; + DDS_IMAGE_DATA * dds; + scene_t * scene = 0; + + switch (caller) { + case PLUGIN_OSMESA_INITOSMESA: + if (!L->isnil(1)) { + scene = (scene_t *) L->touserdata(1); + } + _width = L->tonumber(2); + _height = L->tonumber(3); + if (n == 4) { + upscale = L->toboolean(4); + } else { + upscale = false; + } + L->push(init_OSMesa_context(scene, _width, _height)); + r = 1; + break; + case PLUGIN_OSMESA_FLIPSCENE: + flip_scene((scene_t *) L->touserdata(1), (char *) buffer, width, height, upscale); + break; + case PLUGIN_OSMESA_DUMPSCENE: + if (L->isstring(2)) { + filename = L->tostring(2); + dump_scene((scene_t *) L->touserdata(1), filename, 0, (char *) buffer, width, height, upscale); + } else { + Handle * t = (Handle *) LuaObject::getme(L, 2); + dump_scene((scene_t *) L->touserdata(1), "", t, (char *) buffer, width, height, upscale); + } + break; + case PLUGIN_OSMESA_LOADTEX: + filename = L->tostring(1); + t = filename.to_charp(); + dds = loadDDSTextureFile(t); + L->push((lua_Number) loadCompressedTexture(dds)); + L->push((lua_Number) dds->width); + L->push((lua_Number) dds->height); + destroyDDS(dds); + r = 3; + break; + } + + return r; +} + +static void _init_plugin(Lua * L) { + init_OSMesa(); + Luaplugin_osmesa::pushstatics(L); +} + +extern "C" { + +WEAK void init_plugin(Lua * L) { + _init_plugin(L); +} + +void luaosmesa_init(Lua * L) { + _init_plugin(L); +} + +} |