238 lines
6.1 KiB
C
238 lines
6.1 KiB
C
|
|
||
|
#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;
|
||
|
}
|