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
<< "ESC Programm beenden" << endl
<< "Leertaste Objekt drehen" << endl
<< "+ Hineinzoomen" << endl
<< "- Herauszoomen" << endl
<< "a Textur rotieren" << endl;
263
264 // Starte die Beispiel-Anwendung:
265 sample.start("Stephan Brumme, 702544", true, 512, 512);
266 return(0);
267 }
268
269
270