#ifdef WIN32 #include /* necessary because of the Microsoft OpenGL headers dependency */ #endif #include #include #include #include #include #include #include #include #include #include #include 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; }