You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.3 KiB
150 lines
3.3 KiB
/************************************************************************
|
|
|
|
This is a very simplistic image viewer. It uses libgfx routines to
|
|
read a set of image files specified on the command line. These images
|
|
are then displayed in a window using OpenGL image operations.
|
|
|
|
by Michael Garland, 2000.
|
|
|
|
$Id: t-glimg.cxx 426 2004-09-27 04:34:55Z garland $
|
|
|
|
************************************************************************/
|
|
|
|
#include <gfx/gfx.h>
|
|
#include <gfx/gui.h>
|
|
#include <gfx/raster.h>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <FL/filename.H>
|
|
|
|
class GUI : public MxGUI
|
|
{
|
|
public:
|
|
std::vector<ByteRaster *> images;
|
|
std::vector<std::string> image_names;
|
|
int current_image;
|
|
|
|
virtual ~GUI();
|
|
|
|
virtual void update_animation();
|
|
virtual void cmdline_file(const char *file);
|
|
virtual void setup_for_drawing();
|
|
virtual void draw_contents();
|
|
|
|
void set_image(int i);
|
|
};
|
|
|
|
GUI gui;
|
|
|
|
GUI::~GUI()
|
|
{
|
|
for(int i=0; i<images.size(); i++)
|
|
if( images[i] )
|
|
delete images[i];
|
|
}
|
|
|
|
static void cb_image(Fl_Widget *, long i)
|
|
{ gui.set_image(i); gui.canvas->redraw(); }
|
|
|
|
void GUI::set_image(int i)
|
|
{
|
|
current_image = i;
|
|
|
|
if(current_image<0 || current_image>=images.size()) return;
|
|
ByteRaster *img = images[current_image];
|
|
|
|
int width = img->width();
|
|
int height = img->height();
|
|
|
|
gui.status(image_names[current_image].c_str());
|
|
|
|
if( width!=canvas->w() || height!=canvas->h() )
|
|
{
|
|
unlock_size();
|
|
resize_canvas(width, height);
|
|
lock_size();
|
|
}
|
|
}
|
|
|
|
void GUI::cmdline_file(const char *namestring)
|
|
{
|
|
if(!namestring) return; // Don't support reading from stdin
|
|
|
|
static std::string img_menu("&Images/");
|
|
std::string filename(fl_filename_name(namestring)); // Strip directories
|
|
|
|
ByteRaster *img = read_image(namestring);
|
|
if( img )
|
|
{
|
|
int id = images.size();
|
|
images.push_back(img);
|
|
image_names.push_back(namestring);
|
|
|
|
int key = id<9 ? FL_CTRL+'1'+id : 0;
|
|
|
|
|
|
gui.menu_bar->add((img_menu+filename).c_str(), key,
|
|
(Fl_Callback *)cb_image, (void *)id, FL_MENU_RADIO);
|
|
}
|
|
}
|
|
|
|
void GUI::update_animation()
|
|
{
|
|
set_image((current_image+1) % images.size());
|
|
}
|
|
|
|
void GUI::setup_for_drawing()
|
|
{
|
|
glClearColor(0.9f, 0.0f, 0.0f, 0.0f);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glPixelZoom(1.0f, -1.0f);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
}
|
|
|
|
static void draw_image(const ByteRaster *img)
|
|
{
|
|
GLenum format;
|
|
if(img->channels()==1) format = GL_LUMINANCE;
|
|
else if(img->channels()==3) format = GL_RGB;
|
|
else if(img->channels()==4) format = GL_RGBA;
|
|
else return; // Don't draw unsupported formats
|
|
|
|
glPushAttrib(GL_PIXEL_MODE_BIT);
|
|
glRasterPos2f(0, img->height());
|
|
glDrawPixels(img->width(), img->height(),
|
|
format, GL_UNSIGNED_BYTE, img->head());
|
|
glPopAttrib();
|
|
|
|
}
|
|
|
|
void GUI::draw_contents()
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
if(current_image<0 || current_image>=images.size()) return;
|
|
ByteRaster *img = images[current_image];
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluOrtho2D(0, img->width(), 0, img->height());
|
|
|
|
draw_image(img);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
gui.initialize(argc, argv);
|
|
if(gui.images.size() == 0) return 0; // Exit if no images read
|
|
|
|
gui.title("OpenGL Image Viewer");
|
|
|
|
gui.default_fps = 1.0f;
|
|
gui.set_image(0);
|
|
|
|
return gui.run();
|
|
}
|