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