1 //
2 // Computergraphik II
3 // Prof. Dr. Juergen Doellner
4 // Wintersemester 2001/02
5 //
6 // Rahmenprogramm zu Aufgabenzettel 8
7 //
8
9 #include "cgalphatexture.h"
10 #include <fstream.h>
11 #include <stdlib.h>
12
13 #ifndef M_PI
14 const double M_PI = 3.14159265358979323846;
15 #endif
16
17 const int SLICES = 120;
18
19 CGAlphaTexture::CGAlphaTexture(char* filename) {
20 filename_ = filename;
21
22 // initial threshold, ca. 50% is visible
23 threshold_ = 0.5;
24 // alpha blending is turned on
25 alpha_ = true;
26
27 run_ = false;
28 zoom_ = 1.5;
29 }
30
31
32 CGAlphaTexture::~CGAlphaTexture() {
33 }
34
35 static GLfloat light_position1[] = {0.0, 0.0, 0.0, 1.0}; /* Point light location. */
36
37 void CGAlphaTexture::drawScene() {
38
39 // set alpha function
40 if (alpha_)
41 {
42 glAlphaFunc(GL_GEQUAL, threshold_);
43 glEnable(GL_ALPHA_TEST);
44 }
45 else
46 glDisable(GL_ALPHA_TEST);
47
48
49 glPushMatrix();
50 glRotatef(60,1,0,0);
51 glScaled(zoom_, zoom_, zoom_);
52
53 glBegin(GL_TRIANGLE_FAN);
54 glColor3f(1.0, 1.0, 1.0);
55 glTexCoord2f(0.5, 0.5);
56 glVertex3f(0.0, 0.0, 0.0);
57 for (int i=0; i<=SLICES; i++) {
58
59 double col = 3*i/(double)SLICES;
60 double colfloor = col - (int)col;
61 if (col>=3.0) glColor3f(1.0, 0.0, 0.0);
62 else if (col>=2.0) glColor3f(colfloor, 0, 1.0-colfloor);
63 else if (col>=1.0) glColor3f(0, 1.0-colfloor, colfloor);
64 else glColor3f(1.0-colfloor, colfloor, 0);
65
66 double rad = i/(double)SLICES * M_PI * 2.0;
67
68 // set texture coordinates (same as vertex)
69 glTexCoord2f((cos(rad)+1)/2, (sin(rad)+1)/2);
70 glVertex3f(cos(rad), sin(rad), 0);
71 }
72 glEnd();
73 glPopMatrix();
74 }
75
76 void CGAlphaTexture::readImage() {
77 // reads grayscale PPM-image
78
79 const int BUF_SIZE = 1024;
80
81 char buf[BUF_SIZE];
82
83 // create input stream
84 ifstream in(filename_);
85 if(!in) {
86 cerr << "no ppm image" << endl;
87 exit(-1);
88 }
89
90 cout << "Reading image from file \"" << filename_ << "\" " << endl;
91
92 // PPM header
93 #ifdef _MSC_VER
94 in >> binary;
95 #endif
96
97 // Read "P5"
98 char ppm;
99 in >> ppm; if(!in.good() || ppm != 'P') { cerr << "ppm format error" << endl; }
100 in >> ppm; if(!in.good() || ppm != '5') { cerr << "ppm format error" << endl; }
101
102 // forward to next line
103 in.getline(buf, BUF_SIZE);
104
105 // normally read comments, but we assume that no comments are there
106 // in.getline(buf, BUF_SIZE);
107 // while (buf[0] == '#')
108 // in.getline(buf, BUF_SIZE);
109
110
111 // Read width and height
112 in >> texWidth_; if(!in.good()) { cerr << "ppm format error" << endl; }
113 in >> texHeight_; if(!in.good()) { cerr << "ppm format error" << endl; }
114
115 // Read 255
116 unsigned int res;
117 in >> res; if(!in.good() || res != 255) { cerr << "ppm format error" << endl; }
118
119 // forward to next line
120 in.getline(buf, BUF_SIZE);
121
122 image_ = new GLubyte [texWidth_ * texHeight_];
123 in.read(image_, texWidth_ * texHeight_);
124 if(!in.good()) { cerr << "ppm format error" << endl; }
125
126 in.close();
127 }
128
129 void CGAlphaTexture::onInit() {
130
131 // Tiefen Test aktivieren
132 glEnable(GL_DEPTH_TEST);
133
134 // Smooth Schattierung aktivieren
135 glShadeModel(GL_SMOOTH);
136
137 // Projection
138 glMatrixMode(GL_PROJECTION);
139 gluPerspective(60.0, 1.0, 2.0, 50.0);
140
141 // LookAt
142 glMatrixMode(GL_MODELVIEW);
143 gluLookAt(
144 0.0, 0.0, 4.0, // from (0,0,4)
145 0.0, 0.0, 0.0, // to (0,0,0)
146 0.0, 1.0, 0.); // up
147
148 glClearColor(0.9,0.9,0.9,1.0);
149
150 readImage();
151
152 //////////////////////////////////
153 // create texture
154
155 // generate a unique ID
156 glGenTextures(1, &texName_);
157 // use this texture ID
158 glBindTexture(GL_TEXTURE_2D, texName_);
159
160 // use filter "linear" both for magnification and minification
161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
163
164 // bind image to texture object
165 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texWidth_, texHeight_, 0, GL_ALPHA, GL_UNSIGNED_BYTE, image_);
166
167 // enable texture mapping
168 glEnable(GL_TEXTURE_2D);
169 }
170
171 void CGAlphaTexture::onSize(unsigned int newWidth,unsigned int newHeight) {
172 width_ = newWidth;
173 height_ = newHeight;
174 glMatrixMode(GL_PROJECTION);
175 glViewport(0, 0, width_ - 1, height_ - 1);
176 glLoadIdentity();
177 gluPerspective(40.0,float(width_)/float(height_),2.0, 100.0);
178 glMatrixMode(GL_MODELVIEW);
179 }
180
181 void CGAlphaTexture::onKey(unsigned char key) {
182 switch (key) {
183 case 27: { exit(0); break; }
184 case '+': { zoom_*= 1.1; break; }
185 case '-': { zoom_*= 0.9; break; }
186 case ' ': { run_ = !run_; break; }
187 // increase threshold
188 case 'x': { threshold_ += 0.025;
189 if (threshold_ > 1)
190 threshold_ = 1;
191 cout << "Schwellwert: " << threshold_ << endl;
192 break; }
193 // decrease threshold
194 case 'y': { threshold_ -= 0.025;
195 if (threshold_ < 0)
196 threshold_ = 0;
197 cout << "Schwellwert: " << threshold_ << endl;
198 break; }
199 // enable/disable alpha blending at all
200 case 'a': { alpha_ = !alpha_; break; }
201 }
202
203 onDraw();
204 }
205
206 void CGAlphaTexture::onIdle() {
207
208 if (run_) {
209 glRotatef(.5, 0.0, 1.0, 0.0);
210 }
211 onDraw();
212 }
213
214 void CGAlphaTexture::onDraw() {
215 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
216
217 drawScene();
218
219 swapBuffers();
220 }
221
222 // Hauptprogramm
223 int main(int argc, char* argv[]) {
224 // Erzeuge eine Instanz der Beispiel-Anwendung:
225 CGAlphaTexture sample("alpha.ppm");
226
227 cout << "Tastenbelegung:" << endl
228 << "ESC Programm beenden" << endl
229 << "Leertaste Objekt drehen" << endl
230 << "+ Hineinzoomen" << endl
231 << "- Herauszoomen" << endl
232 << "a Alpha Blending ein/aus" << endl
233 << "x Alpha-Schwellwert erhoehen" << endl
234 << "y Alpha-Schwellwert senken" << endl << endl;
235
236 // Starte die Beispiel-Anwendung:
237 sample.start("Stephan Brumme, 702544", true, 512, 512);
238 return(0);
239 }
240