sources:


website:
more info here


screenshot:
studies/grafik2/Computergrafik-Code9/Aufgabe24/cgprojtexture.cpp
download file

  1 //
  2 // Computergraphik II
  3 // Prof. Dr. Juergen Doellner
  4 // Wintersemester 2001/02
  5 //
  6 // Rahmenprogramm zu Aufgabenzettel 9
  7 //
  8
  9 #include "cgprojtexture.h"
 10 #include "vector.h"
 11 #include <fstream.h>
 12 #include <stdlib.h>
 13
 14 #ifndef M_PI
 15 const double M_PI = 3.14159265358979323846;
 16 #endif
 17
 18 const unsigned int BUF_SIZE = 1024;
 19
 20 CGProjTexture::CGProjTexture(char* filename) {
 21     filename_ = filename;
 22
 23     run_ = false;
 24     zoom_ = 0.16;
 25
 26     angle_ = 15.0;
 27     radius_ = 4.0;
 28     theta_ = 0.0;
 29     phi_ = 0.0;
 30 }
 31
 32 CGProjTexture::~CGProjTexture() {
 33
 34
 35 void CGProjTexture::drawScene() {
 36
 37     // texture coordinate generation
 38     static const GLfloat Splane[] = { 1, 0, 0, 0 };
 39     static const GLfloat Tplane[] = { 0, 1, 0, 0 };
 40     static const GLfloat Rplane[] = { 0, 0, 1, 0 };
 41     static const GLfloat Qplane[] = { 0, 0, 0, 1 };
 42     glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
 43     glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
 44     glTexGeni (GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
 45     glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
 46     glTexGenfv(GL_S, GL_EYE_PLANE, Splane);
 47     glTexGenfv(GL_T, GL_EYE_PLANE, Tplane);
 48     glTexGenfv(GL_R, GL_EYE_PLANE, Rplane);
 49     glTexGenfv(GL_Q, GL_EYE_PLANE, Qplane);
 50
 51     // switch it on
 52     glEnable(GL_TEXTURE_GEN_S);
 53     glEnable(GL_TEXTURE_GEN_T);
 54     glEnable(GL_TEXTURE_GEN_R);
 55     glEnable(GL_TEXTURE_GEN_Q);
 56
 57     // Texturmatrix für projektive Textur einstellen
 58     glMatrixMode(GL_TEXTURE);     
 59
 60     // texture coordinates must be within [0,1]^2
 61     glLoadIdentity();
 62     glTranslatef(0.5, 0.5, 0.0);
 63     glScalef    (0.5,-0.5, 1.0);
 64
 65     // perspective projection
 66     gluPerspective(angle_, 1, 1, 2*radius_);
 67
 68     // convert angles to radiant
 69     const double theta = theta_ / 180*M_PI;
 70     const double phi   = phi_   / 180*M_PI;
 71     // select view
 72     gluLookAt(radius_*sin(theta)*cos(phi), radius_*sin(phi), radius_*cos(theta)*cos(phi), // from
 73               0.0, 0.0, 0.0, // to
 74               0.0, 1.0, 0.0)
;// up
 75    
 76     // Texturierung einschalten
 77     glEnable(GL_TEXTURE_2D);
 78
 79     glMatrixMode(GL_MODELVIEW);     
 80
 81     // draw dino
 82     glPushMatrix();
 83     glScaled(zoom_, zoom_, zoom_);
 84     drawObject();
 85     glPopMatrix();
 86
 87     // gray cube
 88     static float material_diffuse[] = {0.7, 0.8, 1.0, 1.0};
 89     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material_diffuse);
 90     glCullFace(GL_FRONT);
 91     glutSolidCube(3.0);
 92     glCullFace(GL_BACK);
 93 }
 94
 95 void CGProjTexture::drawObject() {
 96     static float material_diffuse[] = {1.0, 0.6, 0.7, 1.0};
 97     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material_diffuse);
 98
 99     // create display list (done only once)
100     static GLuint cache = 0;
101     if (cache == 0) {
102         cache = glGenLists(1);       
103         glNewList(cache, GL_COMPILE);       
104         glMatrixMode(GL_MODELVIEW);
105         glPushMatrix();
106
107         ifstream s("triceratops.txt")
108         char buf[BUF_SIZE];               
109
110         glBegin(GL_TRIANGLES);
111         Vector v[3];               
112         while (!s.eof()) {
113             s >> buf;
114            
115             while (s.good()) {           
116                 s >> v[0] >> v[1] >> v[2];
117                 Vector n = (v[1]-v[0])*(v[2]-v[0]);
118                 glNormal3dv(n.rep());
119                 glVertex3dv(v[0].rep());
120                 glVertex3dv(v[1].rep());
121                 glVertex3dv(v[2].rep());
122             }
123             if (s.rdstate() & ios::failbit) {
124                 s.clear(s.rdstate() & ~ios::failbit);                                         
125             }
126         }
127         glEnd();   
128         glPopMatrix();
129         glEndList();
130     }
131
132     // execute display list
133     glCallList(cache);   
134 }
135
136 void CGProjTexture::readImage() {
137
138     char buf[BUF_SIZE];
139
140     // create input stream
141     ifstream in(filename_);
142     if(!in) {
143         cerr << "no ppm image" << endl;
144         exit(-1);
145     }
146
147     cout << "Reading image from file \"" << filename_ << "===>\<===" " << endl;
148
149     // PPM header
150 #ifdef _MSC_VER
151     in >> binary;
152 #endif
153
154     // Read "P6"
155     char ppm;
156     in >> ppm; if(!in.good() || ppm != 'P') { cerr << "ppm format error" << endl; }
157     in >> ppm; if(!in.good() || ppm != '6') { cerr << "ppm format error" << endl; }
158
159     // forward to next line
160     in.getline(buf, BUF_SIZE);
161
162     // normally read comments, but we assume that no comments are there
163     // in.getline(buf, BUF_SIZE);
164     // while (buf[0] == '#')
165     // in.getline(buf, BUF_SIZE);
166
167     // Read width and height
168     in >> texWidth_; if(!in.good()) { cerr << "ppm format error" << endl; }
169     in >> texHeight_; if(!in.good()) { cerr << "ppm format error" << endl; }
170
171     // Read 255
172     unsigned int res;
173     in >> res; if(!in.good() || res != 255) { cerr << "ppm format error" << endl; }
174
175     // forward to next line
176     in.getline(buf, BUF_SIZE);
177    
178     image_ = new GLubyte [3 * texWidth_ * texHeight_];
179     in.read(image_, 3 * texWidth_ * texHeight_);
180     if(!in.good()) { cerr << "ppm format error" << endl; }
181
182     in.close();
183 }
184
185 void CGProjTexture::onInit() {
186    
187     // Tiefen Test aktivieren
188     glEnable(GL_DEPTH_TEST);
189    
190     // Smooth Schattierung aktivieren
191     glShadeModel(GL_SMOOTH);
192
193     // Culling aktivieren
194     glCullFace(GL_BACK);
195     glEnable(GL_CULL_FACE);
196    
197     // Projection
198     glMatrixMode(GL_PROJECTION);
199     gluPerspective(40.0, 1.0, 1.0, 20.0);   
200    
201     // LookAt
202     glMatrixMode(GL_MODELVIEW);
203     gluLookAt(
204         0.0, 0.0, 4.0,  // from (0,0,4)
205         0.0, 0.0, 0.0,  // to (0,0,0)
206         0.0, 1.0, 0.)
// up
207    
208     glClearColor(0.9,0.9,0.9,1.0);
209
210     // Textur einlesen
211     readImage();
212     // Texturobjekt anlegen, Grundeinstellungen für projektive Textur festlegen
213
214     //////////////////////////////////
215     // create texture
216
217     // generate a unique ID
218     glGenTextures(1, &texName_);
219     // use this texture ID
220     glBindTexture(GL_TEXTURE_2D, texName_);
221
222     // don't repeat texture
223     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
224     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
225     // use filter "linear" both for magnification and minification
226     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
227     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
228
229     // bind image to texture object
230     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth_, texHeight_, 0, GL_RGB, GL_UNSIGNED_BYTE, image_);
231
232     // texture blending
233     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
234
235     // OpenGL Lichtquellen
236     static GLfloat light_diffuse[] = {0.7, 0.7, 0.7, 1.0};     
237     static GLfloat light_position1[] = {1.0, 0.5, 1.0, 0.0};     
238     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
239     glLightfv(GL_LIGHT0, GL_POSITION, light_position1);
240     glEnable(GL_LIGHT0);
241
242     static GLfloat light_position2[] = {-0.5, -0.4, -1.0, 0.0};   
243     glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
244     glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
245     glEnable(GL_LIGHT1);
246     glEnable(GL_LIGHTING);
247 }
248
249 void CGProjTexture::onSize(unsigned int newWidth,unsigned int newHeight) {         
250     width_ = newWidth;
251     height_ = newHeight;           
252     glMatrixMode(GL_PROJECTION);
253     glViewport(0, 0, width_ - 1, height_ - 1);       
254     glLoadIdentity();
255     gluPerspective(40.0,float(width_)/float(height_),1.0, 20.0);
256     glMatrixMode(GL_MODELVIEW);     
257 }
258
259 void CGProjTexture::onKey(unsigned char key) {
260     switch (key) {
261     case 27: { exit(0); break; }                       
262     case '+': { zoom_*= 1.1; break; }
263     case '-': { zoom_/= 1.1; break; }
264     case ' ': { run_ = !run_; break; }
265     case 'w': { if (angle_ < 180) angle_ *= 1.05; break; }
266     case 'q': { if (angle_ > 0.001) angle_ /= 1.05; break; }
267     case 's': { theta_ += 2; if (theta_>=360) theta_-=360; break; }
268     case 'a': { theta_ -= 2; if (theta_<=0) theta_+=360; break; }
269     case 'x': { phi_ += 2; if (phi_>=90) phi_=90; break; }
270     case 'y': { phi_ -= 2; if (phi_<=-90) phi_=-90;break; }
271     }
272     onDraw();
273 }
274
275 void CGProjTexture::onIdle() {
276
277     if (run_) {
278         glRotatef(.5, 0.0, 1.0, 0.0);
279     }
280     onDraw();
281 }
282
283 void CGProjTexture::onDraw() {
284     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
285
286     drawScene();
287
288     swapBuffers();
289 }
290
291 // Hauptprogramm
292 int main(int argc, char* argv[]) {
293     // Erzeuge eine Instanz der Beispiel-Anwendung:
294     CGProjTexture sample("smily.ppm");
295    
296     cout << "Tastenbelegung:" << endl          << "ESC Programm beenden" << endl          << "Leertaste Objekt drehen" << endl          << "+ Hineinzoomen" << endl          << "- Herauszoomen" << endl          << "q Textur verkleinern" << endl          << "w Textur vergroessern" << endl          << "a Textur nach rechts schwenken" << endl          << "s Textur nach links schwenken" << endl          << "y Textur nach oben schwenken" << endl          << "x Textur nach unten schwenken" << endl;
297
298     // Starte die Beispiel-Anwendung:
299     sample.start("Stephan Brumme, 702544", true, 512, 512);
300     return(0);
301 }
302