// // Computergraphik II // Prof. Dr. Juergen Doellner // Wintersemester 2001/02 // // Rahmenprogramm zu Aufgabenzettel 8 // #include "cgalphatexture.h" #include #include #ifndef M_PI const double M_PI = 3.14159265358979323846; #endif const int SLICES = 120; CGAlphaTexture::CGAlphaTexture(char* filename) { filename_ = filename; // initial threshold, ca. 50% is visible threshold_ = 0.5; // alpha blending is turned on alpha_ = true; run_ = false; zoom_ = 1.5; } CGAlphaTexture::~CGAlphaTexture() { } static GLfloat light_position1[] = {0.0, 0.0, 0.0, 1.0}; /* Point light location. */ void CGAlphaTexture::drawScene() { // set alpha function if (alpha_) { glAlphaFunc(GL_GEQUAL, threshold_); glEnable(GL_ALPHA_TEST); } else glDisable(GL_ALPHA_TEST); glPushMatrix(); glRotatef(60,1,0,0); glScaled(zoom_, zoom_, zoom_); glBegin(GL_TRIANGLE_FAN); glColor3f(1.0, 1.0, 1.0); glTexCoord2f(0.5, 0.5); glVertex3f(0.0, 0.0, 0.0); for (int i=0; i<=SLICES; i++) { double col = 3*i/(double)SLICES; double colfloor = col - (int)col; if (col>=3.0) glColor3f(1.0, 0.0, 0.0); else if (col>=2.0) glColor3f(colfloor, 0, 1.0-colfloor); else if (col>=1.0) glColor3f(0, 1.0-colfloor, colfloor); else glColor3f(1.0-colfloor, colfloor, 0); double rad = i/(double)SLICES * M_PI * 2.0; // set texture coordinates (same as vertex) glTexCoord2f((cos(rad)+1)/2, (sin(rad)+1)/2); glVertex3f(cos(rad), sin(rad), 0); } glEnd(); glPopMatrix(); } void CGAlphaTexture::readImage() { // reads grayscale PPM-image const int BUF_SIZE = 1024; char buf[BUF_SIZE]; // create input stream ifstream in(filename_); if(!in) { cerr << "no ppm image" << endl; exit(-1); } cout << "Reading image from file \"" << filename_ << "\" " << endl; // PPM header #ifdef _MSC_VER in >> binary; #endif // Read "P5" char ppm; in >> ppm; if(!in.good() || ppm != 'P') { cerr << "ppm format error" << endl; } in >> ppm; if(!in.good() || ppm != '5') { cerr << "ppm format error" << endl; } // forward to next line in.getline(buf, BUF_SIZE); // normally read comments, but we assume that no comments are there // in.getline(buf, BUF_SIZE); // while (buf[0] == '#') // in.getline(buf, BUF_SIZE); // Read width and height in >> texWidth_; if(!in.good()) { cerr << "ppm format error" << endl; } in >> texHeight_; if(!in.good()) { cerr << "ppm format error" << endl; } // Read 255 unsigned int res; in >> res; if(!in.good() || res != 255) { cerr << "ppm format error" << endl; } // forward to next line in.getline(buf, BUF_SIZE); image_ = new GLubyte [texWidth_ * texHeight_]; in.read(image_, texWidth_ * texHeight_); if(!in.good()) { cerr << "ppm format error" << endl; } in.close(); } void CGAlphaTexture::onInit() { // Tiefen Test aktivieren glEnable(GL_DEPTH_TEST); // Smooth Schattierung aktivieren glShadeModel(GL_SMOOTH); // Projection glMatrixMode(GL_PROJECTION); gluPerspective(60.0, 1.0, 2.0, 50.0); // LookAt glMatrixMode(GL_MODELVIEW); gluLookAt( 0.0, 0.0, 4.0, // from (0,0,4) 0.0, 0.0, 0.0, // to (0,0,0) 0.0, 1.0, 0.); // up glClearColor(0.9,0.9,0.9,1.0); readImage(); ////////////////////////////////// // create texture // generate a unique ID glGenTextures(1, &texName_); // use this texture ID glBindTexture(GL_TEXTURE_2D, texName_); // use filter "linear" both for magnification and minification glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // bind image to texture object glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texWidth_, texHeight_, 0, GL_ALPHA, GL_UNSIGNED_BYTE, image_); // enable texture mapping glEnable(GL_TEXTURE_2D); } void CGAlphaTexture::onSize(unsigned int newWidth,unsigned int newHeight) { width_ = newWidth; height_ = newHeight; glMatrixMode(GL_PROJECTION); glViewport(0, 0, width_ - 1, height_ - 1); glLoadIdentity(); gluPerspective(40.0,float(width_)/float(height_),2.0, 100.0); glMatrixMode(GL_MODELVIEW); } void CGAlphaTexture::onKey(unsigned char key) { switch (key) { case 27: { exit(0); break; } case '+': { zoom_*= 1.1; break; } case '-': { zoom_*= 0.9; break; } case ' ': { run_ = !run_; break; } // increase threshold case 'x': { threshold_ += 0.025; if (threshold_ > 1) threshold_ = 1; cout << "Schwellwert: " << threshold_ << endl; break; } // decrease threshold case 'y': { threshold_ -= 0.025; if (threshold_ < 0) threshold_ = 0; cout << "Schwellwert: " << threshold_ << endl; break; } // enable/disable alpha blending at all case 'a': { alpha_ = !alpha_; break; } } onDraw(); } void CGAlphaTexture::onIdle() { if (run_) { glRotatef(.5, 0.0, 1.0, 0.0); } onDraw(); } void CGAlphaTexture::onDraw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawScene(); swapBuffers(); } // Hauptprogramm int main(int argc, char* argv[]) { // Erzeuge eine Instanz der Beispiel-Anwendung: CGAlphaTexture sample("alpha.ppm"); cout << "Tastenbelegung:" << endl << "ESC Programm beenden" << endl << "Leertaste Objekt drehen" << endl << "+ Hineinzoomen" << endl << "- Herauszoomen" << endl << "a Alpha Blending ein/aus" << endl << "x Alpha-Schwellwert erhoehen" << endl << "y Alpha-Schwellwert senken" << endl << endl; // Starte die Beispiel-Anwendung: sample.start("Stephan Brumme, 702544", true, 512, 512); return(0); }