diff options
Diffstat (limited to 'test/iupglview.c')
-rw-r--r-- | test/iupglview.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/test/iupglview.c b/test/iupglview.c new file mode 100644 index 0000000..93e0054 --- /dev/null +++ b/test/iupglview.c @@ -0,0 +1,237 @@ + +#ifdef WIN32 +#include <windows.h> /* necessary because of the Microsoft OpenGL headers dependency */ +#endif + +#include <GL/gl.h> +#include <GL/glu.h> + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include <iup.h> +#include <iupgl.h> + +#include <im.h> +#include <im_image.h> +#include <im_util.h> +#include <im_convert.h> + +int app_repaint_cb(Ihandle* self) +{ + unsigned char* gl_data = (unsigned char*)IupGetAttribute(self, "APP_GL_DATA"); + int width = IupGetInt(self, "APP_GL_WIDTH"); + int height = IupGetInt(self, "APP_GL_HEIGHT"); + IupGLMakeCurrent(self); /* activates this GL Canvas as the current drawing area. */ + glClear(GL_COLOR_BUFFER_BIT); /* clears the back buffer */ + + if (gl_data) + { + /* Draws the captured image at (0,0) */ + glRasterPos2f(0.f, 0.f); + glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, gl_data); + } + + IupGLSwapBuffers(self); /* swap data from back buffer to front buffer */ + return IUP_DEFAULT; +} + +void appGLInit(int width, int height) +{ + glClearColor(0., 0., 0., 1.0); /* window background */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* data alignment is 1 */ + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D (0.0, (GLdouble)width, 0.0, (GLdouble)height); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +int app_resize_cb(Ihandle* self, int width, int height) +{ + IupGLMakeCurrent(self); + appGLInit(width, height); + return IUP_DEFAULT; +} + +/* OpenGL does not supports palette based images, so convert to RGB */ +/* this function can also be use for RGBA images */ +void ConvertMapToGLData(unsigned char* data, int count, int depth, long* palette, int palette_count) +{ + int c, i; + unsigned char r[256], g[256], b[256]; + + unsigned char* src_data = data + count-1; + unsigned char* dst_data = data + depth*(count-1); + + for (c = 0; c < palette_count; c++) + imColorDecode(&r[c], &g[c], &b[c], palette[c]); + + for (i = 0; i < count; i++) + { + int index = *src_data; + *dst_data = r[index]; + *(dst_data+1) = g[index]; + *(dst_data+2) = b[index]; + + dst_data -= depth; + src_data--; + } +} + +int app_open_cb(Ihandle* self) +{ + imFile* ifile; /* file input */ + int ret, error; + unsigned char* gl_data = (unsigned char*)IupGetAttribute(self, "APP_GL_DATA"); + char filename[1024] = ".\\*.*"; + + /* get a file name */ + ret = IupGetFile(filename); + if (ret == -1) + return IUP_DEFAULT; + + ifile = imFileOpen(filename, &error); + if (!ifile) + { + IupMessage("Error", "Error reading image file."); + return IUP_DEFAULT; + } + + { + int width = 0, height = 0, file_color_mode, color_space; + Ihandle* dialog = IupGetDialog(self); + imFileReadImageInfo(ifile, 0, &width, &height, &file_color_mode, NULL); + + /* alocates the buffers */ + if (gl_data) free(gl_data); + gl_data = malloc(width*height*3); + IupSetAttribute(dialog, "APP_GL_DATA", gl_data); + IupSetfAttribute(dialog, "APP_GL_WIDTH", "%d", width); + IupSetfAttribute(dialog, "APP_GL_HEIGHT", "%d", height); + + imFileReadImageData(ifile, gl_data, 1, IM_PACKED); + + color_space = imColorModeSpace(file_color_mode); + if (color_space == IM_MAP || color_space == IM_GRAY || color_space == IM_BINARY) + { + long palette[256]; + int palette_count; + imFileGetPalette(ifile, palette, &palette_count); + ConvertMapToGLData(gl_data, width*height, 3, palette, palette_count); + } + } + + imFileClose(ifile); + + return IUP_DEFAULT; +} + +int app_exit_cb(Ihandle *self) +{ + unsigned char* gl_data = (unsigned char*)IupGetAttribute(self, "APP_GL_DATA"); + + /* destroy buffers */ + if (gl_data) + free(gl_data); + + return IUP_CLOSE; +} + +int app_about_cb(Ihandle *self) +{ + IupMessagef("About", "IUPGLView 1.0\n" + "Tecgraf/PUC-Rio\n" + " ---------------- \n" + "IUP Version %s\n" + "IM Version %s\n" + " ---------------- \n" + "OpenGL:\n" + " Vendor: %s\n" + " Renderer: %s\n" + " Version: %s\n" + , IUP_RELEASE_VERSION, IM_VERSION, + glGetString(GL_VENDOR),glGetString(GL_RENDERER),glGetString(GL_VERSION)); + return IUP_DEFAULT; +} + +void mainMenuCreate(void) +{ + Ihandle* file_menu = IupMenu( + IupItem( "Open...", "app_open_cb"), + IupSeparator(), + IupItem( "Exit", "app_exit_cb"), + NULL + ); + + Ihandle* menu = IupMenu( + IupSubmenu("File", file_menu), + NULL + ); + + /* this will be used by the dialog */ + IupSetHandle("app_menu", menu); + + IupSetFunction("app_open_cb", (Icallback)app_open_cb); + IupSetFunction("app_exit_cb", (Icallback)app_exit_cb); +} + +void mainDialogCreate(void) +{ + Ihandle *dialog, *box, *canvas; + + /* initialize interface */ + + /* canvas for the image */ + + canvas = IupGLCanvas("app_repaint_cb"); + IupSetAttribute(canvas, "BORDER", "NO"); + IupSetAttribute(canvas, "BUFFER", "DOUBLE"); /* use double buffer */ + IupSetAttribute(canvas, "RESIZE_CB", "app_resize_cb"); /* configure the resize callback */ + + IupSetFunction("app_resize_cb", (Icallback)app_resize_cb); + IupSetFunction("app_repaint_cb", (Icallback)app_repaint_cb); + + /* this is the most external box that puts together + the toolbar, the two canvas and the status bar */ + box = IupSetAttributes(IupHbox( + canvas, + NULL), "MARGIN=10x10"); + + /* create the dialog and set its attributes */ + + mainMenuCreate(); + + dialog = IupDialog(box); + IupSetAttribute(dialog, "MENU", "app_menu"); /* configure the menu */ + IupSetAttribute(dialog, "CLOSE_CB", "app_exit_cb"); + IupSetAttribute(dialog, "TITLE", "IUPGLView"); + IupSetAttribute(dialog, "RASTERSIZE", "680x380"); /* initial size */ + IupSetAttribute(dialog, "SHRINK", "YES"); + IupSetHandle("app_dialog", dialog); + + IupShowXY(dialog, IUP_CENTER, IUP_CENTER); +} + +int main(int argc, char* argv[]) +{ + /* IUP initialization */ + IupOpen(); + IupGLCanvasOpen(); + + /* Create and show the main dialog */ + mainDialogCreate(); + + /* IUP event loop */ + IupMainLoop(); + + /* IUP closing */ + IupClose(); + + return 0; +} |