summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2008-08-05 15:03:30 +0000
committerpixel <pixel>2008-08-05 15:03:30 +0000
commitf3c88af7e5db334fbce6cc4399e6b7e41dc33812 (patch)
tree9f2625af982d5804a2467c24cee357eac77024e1
parentc74c464c4526232902264c66e8b52ebfbcc71e1b (diff)
Adding the luaosmesa plugin.
-rw-r--r--Makefile41
-rw-r--r--src/plugin-luaosmesa.cc254
2 files changed, 280 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index d704574..5b6417c 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
+}
+
+}