sources:


website:
more info here


screenshot:
studies/grafik2/Computergrafik-Code4/Aufgabe10/cgillumination.cpp
download file

  1 //
  2 // Computergraphik II
  3 // Prof. Dr. Juergen Doellner
  4 // Wintersemester 2001/02
  5 //
  6 // Rahmenprogramm zu Aufgabenzettel 1
  7 //
  8
  9 #include "cgillumination.h"
 10 #include <fstream.h>
 11
 12 typedef Vector Camera;
 13 typedef Vector Color;
 14
 15 const MAXLIGHTSOURCES = 8;
 16
 17 class Light {
 18 public:   
 19     Light(const Vector& p, double i) : pos(p),intensity(i) {
 20         constant = 0.3;
 21         linear = 0.0;
 22         quadric = 0.0;
 23     }
 24    
 25     Vector pos;                  /* position, world coordinate system */
 26     double intensity;            /* light source intensity [0,1] */
 27     static double ambient;       /* ambient light contribution (global) */
 28
 29     double constant;             /* constant attenuation */     
 30     double linear;               /* linear attenuation */
 31     double quadric;              /* quadric attenuation */
 32 };
 33
 34 double Light::ambient = 0.2;
 35
 36 class Material {
 37 public:
 38     Material(double ka_,double kd_,double ks_,double n_, Color c)
 39         : ka(ka_), kd(kd_), ks(ks_), n(n_), color(c) {}
 40    
 41     double ka;                   /* ambient reflection coefficient */
 42     double kd;                   /* diffuse reflection coefficient */
 43     double ks;                   /* specular reflection coefficient */
 44     double n;                    /* specular shininess */
 45     Color color;                 /* specular color */
 46 };
 47
 48 class Context {   
 49 public:
 50     Light* light[MAXLIGHTSOURCES];             /* max. 8 light sources */
 51     Camera* camera;
 52     Material* material;
 53 };
 54
 55
 56 //
 57 // CGIllumination Application
 58 //
 59
 60 CGIllumination::CGIllumination() {
 61    
 62     stop_=true;
 63     phong_=true;
 64     zoom_=0.3;
 65     rotate_=-30;
 66    
 67     // read triangle data
 68     ifstream s("triceratops.txt");   
 69     //ifstream s("triangle_small.txt");
 70     s >> size_;
 71    
 72     tris_ = new Triangle[size_];
 73
 74     int i;
 75     for (i = 0; i < size_; i++)
 76         s >> tris_[i];
 77    
 78     // init context
 79     ctx_= new Context();   
 80     ctx_->material = new Material(0.6, 0.4, 0.2, 32.0 , Color(0.4, 0.9, 0.4));
 81     ctx_->camera = new Camera(0, 3, 7);
 82     ctx_->light[0] = new Light(Vector( -1, 2, 6), 0.7 );
 83     ctx_->light[1] = new Light(Vector( 9, 4, 1), 1.0 );
 84     ctx_->light[2] = 0;
 85 }
 86
 87
 88 CGIllumination::~CGIllumination() {   
 89 }
 90
 91 void CGIllumination::onInit() {
 92    
 93     // zu Beginn keine OpenGL Lichtquelle
 94     glDisable(GL_LIGHTING);
 95
 96     const float specular[]  = { 0, ctx_->light[0]->intensity, 0, 0 };
 97     glMaterialfv(GL_FRONT, GL_SPECULAR,  specular);
 98     glMaterialf (GL_FRONT, GL_SHININESS, ctx_->material->n);
 99
100     const float lightPosition0[] = { ctx_->light[0]->pos[0],
101                                      ctx_->light[0]->pos[1],
102                                      ctx_->light[0]->pos[2], 0 };
103     const float lightDiffuse0[] = { 0, ctx_->light[0]->intensity, 0, 0 };
104     glLightfv(GL_LIGHT0, GL_POSITION, lightPosition0);
105     glLightfv(GL_LIGHT0, GL_DIFFUSE,  lightDiffuse0);
106     glEnable(GL_LIGHT0);
107
108     const float lightPosition1[] = { ctx_->light[1]->pos[0],
109                                       ctx_->light[1]->pos[1],
110                                      ctx_->light[1]->pos[2], 0 };
111     const float lightDiffuse1[] = { 0, ctx_->light[1]->intensity, 0, 0 };
112     glLightfv(GL_LIGHT1, GL_POSITION, lightPosition1);
113     glLightfv(GL_LIGHT1, GL_DIFFUSE,  lightDiffuse1);
114     glEnable(GL_LIGHT1);
115    
116     glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);       
117     glEnable(GL_COLOR_MATERIAL);
118
119    
120     // automatische Normalisierung
121 // glEnable(GL_NORMALIZE);
122    
123     // Tiefen Test aktivieren
124     glEnable(GL_DEPTH_TEST);
125     glDepthFunc(GL_LESS);
126     glClearColor(1.0,1.0,1.0,1.0);   
127    
128     // Smooth Schattierung aktivieren
129     glShadeModel(GL_SMOOTH);
130    
131     // Culling
132     glCullFace(GL_BACK);
133
134     // Projection
135     glMatrixMode(GL_PROJECTION);
136     gluPerspective(40.0,1.0,1.0,10.0);
137    
138     // LookAt
139     glMatrixMode(GL_MODELVIEW);
140     gluLookAt(0.0, 3.0, 7.0,  // from (0,3,7)
141         0.0, 0.0, 0.0,  // to (0,0,0)
142         0.0, 1.0, 0.)
// up
143    
144 }
145 void CGIllumination::onSize(unsigned int newWidth,unsigned int newHeight) {     
146     if((newWidth > 0) && (newHeight > 0)) {
147         // Passe den OpenGL-Viewport an die neue Fenstergroesse an:
148         glViewport(0, 0, newWidth - 1, newHeight - 1);
149        
150         // Passe die OpenGL-Projektionsmatrix an die neue
151         // Fenstergroesse an:
152         glMatrixMode(GL_PROJECTION);
153         glLoadIdentity();
154         gluPerspective(40.0,float(newWidth)/float(newHeight),1.0, 10.0);       
155        
156         // Schalte zurueck auf die Modelview-Matrix
157         glMatrixMode(GL_MODELVIEW);   
158     }
159 }
160
161 void CGIllumination::onKey(unsigned char key) {
162     static GLfloat z = 3.;
163     switch (key) {
164     case 27: { exit(0); break; }               
165     case '+': { zoom_*= 1.1; break; }
166     case '-': { zoom_*= 0.9; break; }
167     case 'l' : { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break; }
168     case 'f' : { glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break; }
169     case '1' : { glEnable(GL_LIGHTING); phong_ = false; break; }
170     case '2' : { glDisable(GL_LIGHTING); phong_ = true; break; }
171     case 'c' : { if (glIsEnabled(GL_CULL_FACE)) { glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); } break; }
172     case ' ' : { stop_ = !stop_; break; } 
173     }
174     onDraw();
175 }
176
177 void CGIllumination::onIdle() {
178     if (!stop_) {
179         rotate_ -= 2;
180         onDraw();
181     }
182 }
183
184 inline double max(double x, double y) {
185     return (x<y) ? y : x;
186 }
187 inline double min(double x, double y) {
188     return (x<y) ? x : y;
189 }
190
191 double CGIllumination::fatt(const Vector& punkt, const Vector& licht, const int li) {
192     double temp = 1/(ctx_->light[li]->constant+
193                         ctx_->light[li]->linear* abs(punkt-licht)+
194                         ctx_->light[li]->quadric*abs2(punkt-licht))
;
195     if (temp>1) {return 1;} else {return temp;};
196 }
197
198
199 void CGIllumination::setPhongIllumination(const Vector& point, const Vector& normal) {
200     // OpenGL's lighting ?
201     if (!phong_)
202     {
203         const Color c = ctx_->material->color;
204         glColor3f(c[0], c[1], c[2]);
205         return;
206     }
207
208     // Phong Beleuchtungsmodell implementieren
209
210     // NOW COMES DA REAL STUFF !!!
211
212     // define intensity variables
213     double dIntensityAmbient  = 0;
214     double dIntensityDiffuse  = 0;
215     double dIntensitySpecular = 0;
216
217     // ambient intensity
218     dIntensityAmbient = Light::ambient * ctx_->material->ka;
219
220     // N = normal
221     const Vector N_norm = normal.normalized();
222     // V = view vector
223     const Vector V = *(ctx_->camera) - point;
224     const Vector V_norm = V.normalized();
225
226     // process all light sources (at most 8)
227     for (int nLight=0; nLight < MAXLIGHTSOURCES; nLight++)
228     {
229         // get a single light source
230         Light* light = ctx_->light[nLight];
231         if (light == NULL)
232             break;
233
234         // L = light vector
235         const Vector L = light->pos - point;
236         const Vector L_norm = L.normalized();
237
238         // N*L
239         const double NdotL = max(dotProduct(N_norm, L_norm), 0);
240         // R*V = (2*N*(N*L)-L)*V
241         const double RdotV = max(dotProduct((2*NdotL*N_norm - L_norm).normalized(), V_norm), 0);
242
243         // attenuation
244         const double dDistance = abs(L);
245         double dAttenuation = 1 / (light->constant + dDistance*light->linear
246                                          + dDistance*dDistance*light->quadric)
;
247         if (dAttenuation > 1)
248             dAttenuation = 1;
249         // attenuation*I
250         const double dAttI  = dAttenuation * light->intensity;
251
252         // diffuse intensity
253         dIntensityDiffuse  += dAttI * ctx_->material->kd * NdotL;
254         // specular intensity
255         dIntensitySpecular += dAttI * ctx_->material->ks * pow(RdotV, ctx_->material->n);
256     }
257    
258     const double dIntensity = dIntensityAmbient + dIntensityDiffuse + dIntensitySpecular;
259
260     // Material color
261     Color c = ctx_->material->color;
262     c *= dIntensity;
263
264     // color per vertex
265     glColor3f(min(c[0],1), min(c[1],1), min(c[2],1));
266 }   
267
268
269 inline Vector rotateYaxis(const Vector& vec, float angle)
270 {
271     Vector result;
272     const float sinus   = sin(angle/180*3.1415926);
273     const float cosinus = cos(angle/180*3.1415926);
274     result[0] = vec[0]*cosinus + vec[2]*sinus;
275     result[1] = vec[1];
276     result[2] =-vec[0]*sinus   + vec[2]*cosinus;
277     return result;
278 }
279
280 void CGIllumination::onDraw() {
281     // Loesche den Farb- und Tiefenspeicher
282     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   
283    
284    
285     glPushMatrix();
286 // glRotatef(rotate_,0,1,0);
287 // glScaled(zoom_, zoom_, zoom_);
288
289     glBegin(GL_TRIANGLES);
290     for (int i=0; i<size_; i++)
291     {           
292         const Vector n = rotateYaxis(tris_[i].triangleNormal(), rotate_).normalized();
293         glNormal3dv(n.rep());
294         for (int k = 0; k < 3; k++) {
295             const Vector v = rotateYaxis(tris_[i].getVertex(k), rotate_) * zoom_;
296             setPhongIllumination(v,n);     
297             glVertex3dv(v.rep());
298         }       
299     }
300     glEnd();
301    
302     glPopMatrix();   
303    
304     // Nicht vergessen! Front- und Back-Buffer tauschen:
305     swapBuffers();
306 }
307
308 // Hauptprogramm
309 int main(int argc, char* argv[]) {
310     // Erzeuge eine Instanz der Beispiel-Anwendung:
311     CGIllumination sample;
312    
313     cout << "Tastenbelegung:" << endl          << "ESC Programm beenden" << endl          << "Leertaste Objekt drehen" << endl          << "+ Hineinzoomen" << endl          << "- Herauszoomen" << endl          << "l Drahtgittermodell" << endl          << "f Oberflaechen zeichnen" << endl          << "1 OpenGL-Beleuchtung (Blinn-Modell)" << endl          << "2 eigene Phong-Beleuchtung" << endl          << "c Rueckseiten zeichnen an/aus" << endl;
314
315     // Starte die Beispiel-Anwendung:
316     sample.start("Stephan Brumme, 702544");
317     return(0);
318 }
319