Home | Documentation | Download | Screenshots | Developper |
Loads image files and textures map polygons with it.
Pedagogical example that shows how to apply a texture on a 3D object. Inpired from the QT texture example.
The Qt QImage class and its convertToGLFormat()
function are used
to load any image format. The image is resized so that its dimensions are powers
of two if needed. Feel free to cut and paste.
#include "qglviewer.h" class Viewer : public QGLViewer { protected : void init(); void draw(); void help(); void loadImage(); void keyPressEvent(QKeyEvent *e); private : float ratio, u_max, v_max; };
#include "textureViewer.h" #include <qapplication.h> int main(int argc, char** argv) { // Read command lines arguments. QApplication application(argc,argv); // Instantiate the viewer, show it on screen. Viewer viewer; viewer.show(); // Set the viewer as the application main widget. application.setMainWidget(&viewer); // Run main loop. return application.exec(); }
#include "textureViewer.h" #include <qimage.h> #include <qfiledialog.h> using namespace qglviewer; using namespace std; void Viewer::init() { // Enable GL textures glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glEnable( GL_TEXTURE_2D ); // Nice texture coordinate interpolation glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); u_max = 1.0; v_max = 1.0; ratio = 1.0; loadImage(); } void Viewer::draw() { // Display the quad glBegin(GL_QUADS); glTexCoord2f(0.0, 1.0-v_max); glVertex2f(-u_max*ratio,-v_max); glTexCoord2f(0.0, 1.0); glVertex2f(-u_max*ratio, v_max); glTexCoord2f(u_max, 1.0); glVertex2f( u_max*ratio, v_max); glTexCoord2f(u_max, 1.0-v_max); glVertex2f( u_max*ratio,-v_max); glEnd(); } void Viewer::loadImage() { QString name = QFileDialog::getOpenFileName(); // In case of Cancel if (name.isEmpty()) return; QImage img(name); if (img.isNull()) { cerr << "Unable to load " << name << ", unsupported file format" << endl; return; } cout << "Loading " << name << ", " << img.width() << "x" << img.height() << " pixels" << endl; // 1E-3 needed. Just try with width=128 and see ! int newWidth = 1<<(int)(1+log(img.width() -1+1E-3) / log(2.0)); int newHeight = 1<<(int)(1+log(img.height()-1+1E-3) / log(2.0)); u_max = img.width() / (float)newWidth; v_max = img.height() / (float)newHeight; if ((img.width()!=newWidth) || (img.height()!=newHeight)) { cout << "Image dimensions are not powers of two, new size is " << newWidth << "x" << newHeight << endl; img = img.copy(0, 0, newWidth, newHeight); } ratio = newWidth / (float)newHeight; QImage glImg = QGLWidget::convertToGLFormat(img); // flipped 32bit RGBA // Bind the img texture... glTexImage2D(GL_TEXTURE_2D, 0, 3, glImg.width(), glImg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glImg.bits()); } void Viewer::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_L : loadImage(); break; default: QGLViewer::keyPressEvent(e); } } void Viewer::help() { cout << endl << "\t\t- - t e x t u r e V i e w e r - -" << endl << endl; cout << "This pedagogical example illustrates how to texture map polygons." << endl << endl; cout << "The Qt QImage class and its convertToGLFormat function are used" << endl; cout << "to load any image format. The image is resized so that its dimensions" << endl; cout << "are powers of two if needed. Feel free to cut and paste." << endl << endl; cout << "Press 'L'(oad) to load a new image." << endl << endl; }
Back to the main page