sources:
cgapplication.cpp (3.2k)
cgapplication.h (3.5k)
cgtexture.cpp (6.2k)
cgtexture.h (1.2k)
vector.cpp (1.4k)
vector.h (4.9k)


binaries:
Release/church_spiral.ppm (192.0k)
Release/texture.exe (28.5k)


website:
more info here


screenshot:
studies/grafik2/Computergrafik-Code7/cgtexture.cpp
download file

  1 //
  2 // Computergraphik II
  3 // Prof. Dr. Juergen Doellner
  4 // Wintersemester 2001/02
  5 //
  6 // Rahmenprogramm zu Aufgabenzettel 7
  7 //
  8
  9 #include "cgtexture.h"
 10 #include "vector.h"
 11 #include <fstream.h>
 12 #include <stdlib.h>
 13
 14 #ifndef PI
 15 const double PI = 3.14159265358979323846;
 16 #endif
 17
 18 const unsigned int BUF_SIZE = 1024;
 19 const unsigned int PATCH_SIZE = 20;
 20
 21 CGTexture::CGTexture(char* filename) {
 22     filename_ = filename;
 23
 24     run_ = false;
 25     rotate_ = false;
 26
 27     zoom_ = 1.5;
 28     list_ = NULL;
 29    
 30     buildPatch(PATCH_SIZE);
 31 }
 32
 33 CGTexture::~CGTexture() {
 34 }
 35
 36 void CGTexture::drawScene() {
 37
 38     glPushMatrix();
 39     glRotatef(60,1,0,0);
 40     glScaled(zoom_, zoom_, zoom_);
 41
 42     drawObject();
 43     glPopMatrix();
 44 }
 45
 46 void CGTexture::handleVertex(const Vector& v) {
 47     // Hier müssen die Texturkoordinaten berechnet werden
 48     glTexCoord2f(v[0]+0.5, v[2]+0.5);
 49
 50     // draw patch
 51     glVertex3dv(v.rep());
 52 }
 53
 54 void CGTexture::drawObject() {
 55     // draw geometry
 56
 57     glBindTexture(GL_TEXTURE_2D, textureID_);
 58
 59     int c=0;
 60     for(int j=0; j<num_; j++) {
 61         glBegin(GL_TRIANGLE_STRIP); // Performance
 62
 63         for(int i=0; i<((num_+1)*2); i++) {
 64             handleVertex(list_[c]); c++;
 65         }
 66
 67         glEnd();
 68     }
 69 }
 70
 71 void CGTexture::buildPatch(int detail) {
 72     if(list_) delete list_;
 73     list_ = new Vector[(detail)*(4+((detail-1)*2))];
 74
 75     double offset = 1.0/detail;
 76
 77     double x;
 78     double z;
 79     num_ = detail;
 80     int c = 0;
 81     for(int j=0; j<detail; j++) {
 82         x = -0.5;
 83         z =  0.5 - (j+1)*offset;
 84         list_[c] = Vector(x,0,z); c++;
 85
 86         x = -0.5;
 87         z =  0.5 - j*offset;
 88         list_[c] = Vector(x,0,z); c++;
 89
 90         x = -0.5 + offset;
 91         z =  0.5 - (j+1)*offset;
 92         list_[c] = Vector(x,0,z); c++;
 93
 94         for(int i=0; i<detail; ) {
 95             if( (c%2)!=0) {
 96                 x = -0.5 + (i+1)*offset;
 97                 z =  0.5 - (j)*offset;
 98                 i++;
 99             } else {
100                 x = -0.5 + (i+1)*offset;
101                 z =  0.5 - (j+1)*offset;
102             }
103             list_[c] = Vector(x,0,z); c++;
104         }
105     }
106 }
107
108 void CGTexture::readImage() {
109
110     char buf[BUF_SIZE];
111
112     // create input stream
113     ifstream in(filename_);
114     if(!in) {
115         cerr << "no ppm image" << endl;
116         exit(-1);
117     }
118
119     cout << "Reading image from file \"" << filename_ << "\" " << endl;
120
121     // PPM header
122 #ifdef _MSC_VER
123     in >> binary;
124 #endif
125
126     // Read "P6"
127     char ppm;
128     in >> ppm; if(!in.good() || ppm != 'P') { cerr << "ppm format error" << endl; }
129     in >> ppm; if(!in.good() || ppm != '6') { cerr << "ppm format error" << endl; }
130
131     // forward to next line
132     in.getline(buf, BUF_SIZE);
133
134     // normally read comments, but we assume that no comments are there
135
136     // Read width and height
137     in >> texWidth_; if(!in.good()) { cerr << "ppm format error" << endl; }
138     in >> texHeight_; if(!in.good()) { cerr << "ppm format error" << endl; }
139
140     // Read 255
141     unsigned int res;
142     in >> res; if(!in.good() || res != 255) { cerr << "ppm format error" << endl; }
143
144     // forward to next line
145     in.getline(buf, BUF_SIZE);
146    
147     // read image data
148     image_ = new GLubyte [3 * texWidth_ * texHeight_];
149     in.read(image_, 3 * texWidth_ * texHeight_);
150     if(!in.good()) { cerr << "ppm format error" << endl; }
151
152     in.close();
153 }
154
155 void CGTexture::onInit() {
156    
157     // Tiefen Test aktivieren
158     glEnable(GL_DEPTH_TEST);
159    
160     // Smooth Schattierung aktivieren
161     glShadeModel(GL_SMOOTH);
162    
163     // Projection
164     glMatrixMode(GL_PROJECTION);
165     gluPerspective(60.0, 1.0, 2.0, 50.0);   
166    
167     // LookAt
168     glMatrixMode(GL_MODELVIEW);
169     gluLookAt(
170         0.0, 0.0, 4.0,  // from (0,0,4)
171         0.0, 0.0, 0.0,  // to (0,0,0)
172         0.0, 1.0, 0.)
// up
173    
174     glClearColor(0.9,0.9,0.9,1.0);
175
176     // liest ein ppm-bild im format RGB ein (kein alpha-kanal!)
177     readImage();
178
179     //////////////////////////////////
180     // create texture
181
182     // generate a unique ID
183     glGenTextures(1, &textureID_);
184     // use this texture ID
185     glBindTexture(GL_TEXTURE_2D, textureID_);
186
187     // repeat texture if necessary
188     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
189     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
190     // use filter "linear" both for magnification and minification
191     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
192     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
193
194     // bind image to texture object
195     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth_, texHeight_, 0, GL_RGB, GL_UNSIGNED_BYTE, image_);
196
197     // enable texture mapping
198     glEnable(GL_TEXTURE_2D);
199 }
200
201 void CGTexture::onSize(unsigned int newWidth,unsigned int newHeight) {         
202     width_ = newWidth;
203     height_ = newHeight;           
204     glMatrixMode(GL_PROJECTION);
205     glViewport(0, 0, width_ - 1, height_ - 1);       
206     glLoadIdentity();
207     gluPerspective(40.0,float(width_)/float(height_),2.0, 100.0);
208     glMatrixMode(GL_MODELVIEW);     
209 }
210
211 void CGTexture::onKey(unsigned char key) {
212     switch (key) {
213     case 27: { exit(0); break; }                       
214     case '+': { zoom_*= 1.1; break; }
215     case '-': { zoom_*= 0.9; break; }
216     case ' ': { run_ = !run_; break; }
217     case 'a': { rotate_ = !rotate_; break; };
218     }
219     onDraw();
220 }
221
222 void CGTexture::onIdle() {
223
224     // rotate object
225     if (run_)
226         glRotatef(.5, 0.0, 1.0, 0.0);
227
228     // rotate texture
229     if (rotate_)
230     {
231         // use texture matrix stack
232         glMatrixMode(GL_TEXTURE);
233
234         // move origin
235         glTranslatef(0.5, 0.5, 0);
236         // rotate
237         glRotatef(-1, 0, 0, 1);
238         // move back
239         glTranslatef(-0.5, -0.5, 0);
240
241         // switch back to model view matrix stack
242         glMatrixMode(GL_MODELVIEW);
243     }
244
245     onDraw();
246 }
247
248 void CGTexture::onDraw() {
249     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
250
251     drawScene();
252
253     swapBuffers();
254 }
255
256 // Hauptprogramm
257 int main(int argc, char* argv[]) {
258     // Erzeuge eine Instanz der Beispiel-Anwendung:
259     CGTexture sample("church_spiral.ppm");
260     //CGTexture sample("deep_spiral.ppm");
261    
262     cout << "Tastenbelegung:" << endl
263          << "ESC Programm beenden" << endl
264          << "Leertaste Objekt drehen" << endl
265          << "+ Hineinzoomen" << endl
266          << "- Herauszoomen" << endl
267          << "a Textur rotieren" << endl;
268
269     // Starte die Beispiel-Anwendung:
270     sample.start("Stephan Brumme, 702544", true, 512, 512);
271     return(0);
272 }
273
274