OpenGL多边形变换和裁剪

  1 // Computer Graphics: HW2
  2 // 3D Rendering pipeline:
  3 // Space Transformation and Polygon clipping use Sutherland-Hodgman Algorithm
  4   5
  6 #include <iostream>
  7 #include <string>
  8 #include <cstdlib>
  9 #include <cmath>
 10 #include <cstdio>
 11 #include <vector>
 12 #include <gl/glut.h>
 13 #include <iomanip>
 14
 15 using namespace std;
 16
 17 const int dimension = 3;
 18 const double PI = acos(-1);
 19 const double eps = 0.0000001;
 20
 21 struct mat {                    //定义矩阵用作变换操作
 22     float m[3][3];
 23     mat()
 24     {
 25         memset(m, 0, sizeof(m));
 26     }
 27     void reset_mat()
 28     {
 29         for(int i=0; i<dimension; i++)
 30             for(int j=0; j<dimension; j++)
 31             {
 32                 if(i == j)    m[i][j] = 1;
 33                 else        m[i][j] = 0;
 34             }
 35     }
 36 };
 37
 38 mat T, S, R, TM, WVM, M;
 39
 40 mat operator * (mat a, mat b)        //重载*号实现矩阵乘法
 41 {
 42     mat c;
 43     for(int i=0; i<dimension; i++)
 44         for(int j=0; j<dimension; j++)
 45             for(int k=0; k<dimension; k++)
 46                 c.m[i][j] += (a.m[i][k]*b.m[k][j]);
 47     return c;
 48 }
 49
 50 struct square_point {        //在HP坐标上定义正方形的点
 51     float x;
 52     float y;
 53     float hp;
 54     square_point(){ x=0; y=0; hp=1;}
 55     square_point(float _x, float _y, float _hp=1){ x=_x; y=_y; }
 56 };
 57 vector <square_point> squa_trans[101], squa_view[101]; //储存变换数组,储存显示数组,用二维数组不行的啊
 58 square_point squa_clip[101];    //储存clipping数组的点
 59 int squa_clip_cnt=0;        //计算clipping获得点的个数
 60 int squa_num=0;                //计算正方形个数
 61 int squa_view_num=0;        //计算显示的正方形个数
 62
 63 struct tri_point {        //在HP坐标上定义三角形的点
 64     float x;
 65     float y;
 66     float hp;
 67     tri_point(){ x=0; y=0; hp=1;}
 68     tri_point(float _x, float _y, float _hp=1){ x=_x; y=_y; }
 69 };
 70 vector <tri_point> tri_trans[101], tri_view[101];
 71 tri_point tri_clip[101];
 72 int tri_clip_cnt=0;
 73 int tri_num=0;
 74 int tri_view_num=0;
 75
 76
 77 int cc=0;
 78 string status="none";
 79 int view_num=0;
 80 bool view_flag=0;
 81 float Xwmin, Xwmax, Ywmin, Ywmax, Xvmin, Xvmax, Yvmin, Yvmax;    //viewport的坐标
 82 int height, width;
 83 void displayFunc(void);
 84 void ReadInput(bool& IsExit);
 85 void scale(float sx, float sy);        //放大缩小变换
 86 void rotate(float degree);            //旋转变换
 87 void translate(float tx, float ty);        //平移变换
 88 void reset();
 89 void square();        //创建正方形,并做transformation变换
 90 void triangle();    //创建三角形,并做transformation变换
 91 void view(float Xwmin, float Xwmax, float Ywmin, float Ywmax, float Xvmin, float Xvmax, float Yvmin, float Yvmax); //投影到viewport
 92 void clearData();
 93 void clearScreen();
 94 void initial();        //初始化各个变换矩阵,正方形和三角形个数,以及存储点的向量数组
 95 void DrawWindow();    //画出viewport的框框
 96 void square_clip_judge_1(int i, int size);    //1-st pass in Polygon Clipping
 97 void square_clip_judge_2(int i, int size);    //2-nd pass in Polygon Clipping
 98 void square_clip_judge_3(int i, int size);    //3-rd pass in Polygon Clipping
 99 void square_clip_judge_4(int i, int size);    //4-th pass in Polygon Clipping
100 void square_clipping(int i);        //调用4种clipping
101 void square_save(int i);            //调每次clipping后保存顶点
102 void square_drawing();                //画正方形,调用之前的DrawLine等画线函数
103
104 void tri_clip_judge_1(int i, int size);    //三角形的函数和正方形的定义方式都一样的
105 void tri_clip_judge_2(int i, int size);
106 void tri_clip_judge_3(int i, int size);
107 void tri_clip_judge_4(int i, int size);
108 void tri_clipping(int i);
109 void tri_save(int i);
110 void tri_drawing();
111
112 void drawDot(int x, int y, float r, float g, float b);    //hw1中已经实现的函数
113 void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange);
114 void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange);
115 void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange);
116 void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange);
117 void DrawLines_4(int x1, int y1, int x2, int y2);
118
119 void DrawWindow()
120 {
121     DrawLines_4(Xvmin, Yvmin, Xvmax, Yvmin);
122     DrawLines_4(Xvmax, Yvmin, Xvmax, Yvmax);
123     DrawLines_4(Xvmax, Yvmax, Xvmin, Yvmax);
124     DrawLines_4(Xvmin, Yvmax, Xvmin, Yvmin);
125 }
126 /*
127 bool judge_in(int x, int y)
128 {
129     if(x > Xvmin && x < Xvmax && y > Yvmin && y < Yvmax)
130             return 1;
131     return 0;
132 }*/
133 ////////////////////////////////////////////////////////////////////////////////square
134 void square_save(int i)
135 {
136     //cout << "squa_view_num : " << squa_view_num << endl;
137     //cout << "squa_clip_cnt : " << squa_clip_cnt << endl;
138
139     squa_view_num = squa_clip_cnt;
140     for(int j=0; j<squa_view_num; j++)
141         squa_view[i][j] = squa_clip[j];
142     squa_clip_cnt=0;
143 }
144 void square_clip_judge_1(int i, int size)
145 {
146     if(size == 0)
147         return ;
148     square_point s, p, t;
149     for(int j=0; j<size-1; j++)
150     {
151         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
152         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
153
154         t.x = Xvmin;
155         t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
156
157         if(s.x >= Xvmin && p.x >= Xvmin)            squa_clip[squa_clip_cnt++] = p;
158         else if(s.x > Xvmin && p.x < Xvmin)        squa_clip[squa_clip_cnt++] = t;
159         else if(s.x < Xvmin && p.x < Xvmin);
160         else if(s.x < Xvmin && p.x > Xvmin)        {squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
161     }
162
163     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
164     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
165
166     t.x = Xvmin;
167     t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
168
169     if(s.x >= Xvmin && p.x >= Xvmin)            squa_clip[squa_clip_cnt++] = p;
170     else if(s.x > Xvmin && p.x < Xvmin)        squa_clip[squa_clip_cnt++] = t;
171     else if(s.x < Xvmin && p.x < Xvmin);
172     else if(s.x < Xvmin && p.x > Xvmin)        {squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
173
174     square_save(i);
175
176 }
177 void square_clip_judge_2(int i, int size)
178 {
179     if(size == 0)
180         return ;
181     square_point s, p, t;
182     for(int j=0; j<size-1; j++)
183     {
184         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
185         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
186
187         t.y = Yvmin;
188         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
189
190         if(s.y >= Yvmin && p.y >= Yvmin)            squa_clip[squa_clip_cnt++] = p;
191         else if(s.y > Yvmin && p.y < Yvmin)        squa_clip[squa_clip_cnt++] = t;
192         else if(s.y < Yvmin && p.y < Yvmin);
193         else if(s.y < Yvmin && p.y > Yvmin)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
194     }
195
196     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
197     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
198
199     t.y = Yvmin;
200     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
201
202     if(s.y >= Yvmin && p.y >= Yvmin)            squa_clip[squa_clip_cnt++] = p;
203     else if(s.y > Yvmin && p.y < Yvmin)        squa_clip[squa_clip_cnt++] = t;
204     else if(s.y < Yvmin && p.y < Yvmin);
205     else if(s.y < Yvmin && p.y > Yvmin)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
206
207     square_save(i);
208
209 }
210 void square_clip_judge_3(int i, int size)
211 {
212     if(size == 0)
213         return ;
214     square_point s, p, t;
215     for(int j=0; j<size-1; j++)
216     {
217         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
218         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
219
220         t.x = Xvmax;
221         //if(abs(p.x-s.x) > eps)
222             t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
223
224         if(s.x <= Xvmax && p.x <= Xvmax)            squa_clip[squa_clip_cnt++] = p;
225         else if(s.x < Xvmax && p.x > Xvmax)        squa_clip[squa_clip_cnt++] = t;
226         else if(s.x > Xvmax && p.x > Xvmax);
227         else if(s.x > Xvmax && p.x < Xvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
228     }
229     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
230     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
231     t.x = Xvmax;
232     //if(abs(p.x-s.x) > eps)
233         t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
234
235     if(s.x <= Xvmax && p.x <= Xvmax)            squa_clip[squa_clip_cnt++] = p;
236     else if(s.x < Xvmax && p.x > Xvmax)        squa_clip[squa_clip_cnt++] = t;
237     else if(s.x > Xvmax && p.x > Xvmax);
238     else if(s.x > Xvmax && p.x < Xvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
239
240     square_save(i);
241
242 }
243 void square_clip_judge_4(int i, int size)
244 {
245     if(size == 0)
246         return ;
247     square_point s, p, t;
248     for(int j=0; j<size-1; j++)
249     {
250         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
251         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
252
253         t.y = Yvmax;
254         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
255
256
257         if(s.y <= Yvmax && p.y <= Yvmax)            squa_clip[squa_clip_cnt++] = p;
258         else if(s.y < Yvmax && p.y > Yvmax)        squa_clip[squa_clip_cnt++] = t;
259         else if(s.y > Yvmax && p.y > Yvmax);
260         else if(s.y > Yvmax && p.y < Yvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
261     }
262     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
263     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
264
265     t.y = Yvmax;
266     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
267
268     if(s.y <= Yvmax && p.y <= Yvmax)            squa_clip[squa_clip_cnt++] = p;
269     else if(s.y < Yvmax && p.y > Yvmax)        squa_clip[squa_clip_cnt++] = t;
270     else if(s.y > Yvmax && p.y > Yvmax);
271     else if(s.y > Yvmax && p.y < Yvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
272
273     square_save(i);
274
275 }
276 void square_clipping(int i)
277 {
278     square_clip_judge_1(i, squa_view_num);
279     square_clip_judge_2(i, squa_view_num);
280     square_clip_judge_3(i, squa_view_num);
281     square_clip_judge_4(i, squa_view_num);
282 }
283 void square_drawing(int i, int size)
284 {
285     DrawLines_4(squa_view[i][size-1].x, squa_view[i][size-1].y, squa_view[i][0].x, squa_view[i][0].y);
286     for(int j=0; j<size-1; j++)
287         DrawLines_4(squa_view[i][j].x, squa_view[i][j].y, squa_view[i][j+1].x, squa_view[i][j+1].y);
288 }
289 ///////////////////////////////////////////////////////////////////////////////////////////////////triangle
290 void tri_clip_judge_1(int i, int size)
291 {
292     if(size == 0)
293         return ;
294     tri_point s, p, t;
295     for(int j=0; j<size-1; j++)
296     {
297         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
298         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
299
300         t.x = Xvmin;
301         t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
302
303         if(s.x >= Xvmin && p.x >= Xvmin)            tri_clip[tri_clip_cnt++] = p;
304         else if(s.x > Xvmin && p.x < Xvmin)        tri_clip[tri_clip_cnt++] = t;
305         else if(s.x < Xvmin && p.x < Xvmin);
306         else if(s.x < Xvmin && p.x > Xvmin)        { tri_clip[tri_clip_cnt++] = t; tri_clip[tri_clip_cnt++] = p; }
307     }
308
309     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
310     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
311
312     t.x = Xvmin;
313     t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
314
315     if(s.x >= Xvmin && p.x >= Xvmin)            tri_clip[tri_clip_cnt++] = p;
316     else if(s.x > Xvmin && p.x < Xvmin)        tri_clip[tri_clip_cnt++] = t;
317     else if(s.x < Xvmin && p.x < Xvmin);
318     else if(s.x < Xvmin && p.x > Xvmin)        { tri_clip[tri_clip_cnt++] = t; tri_clip[tri_clip_cnt++] = p; }
319
320     tri_save(i);
321 }
322 void tri_clip_judge_2(int i, int size)
323 {
324     if(size == 0)
325         return ;
326     tri_point s, p, t;
327     for(int j=0; j<size-1; j++)
328     {
329         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
330         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
331
332         t.y = Yvmin;
333         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
334
335         if(s.y >= Yvmin && p.y >= Yvmin)            tri_clip[tri_clip_cnt++] = p;
336         else if(s.y > Yvmin && p.y < Yvmin)        tri_clip[tri_clip_cnt++] = t;
337         else if(s.y < Yvmin && p.y < Yvmin);
338         else if(s.y < Yvmin && p.y > Yvmin)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
339     }
340
341     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
342     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
343
344     t.y = Yvmin;
345     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
346
347     if(s.y >= Yvmin && p.y >= Yvmin)            tri_clip[tri_clip_cnt++] = p;
348     else if(s.y > Yvmin && p.y < Yvmin)        tri_clip[tri_clip_cnt++] = t;
349     else if(s.y < Yvmin && p.y < Yvmin);
350     else if(s.y < Yvmin && p.y > Yvmin)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
351
352     tri_save(i);
353 }
354 void tri_clip_judge_3(int i, int size)
355 {
356     if(size == 0)
357         return ;
358     tri_point s, p, t;
359     for(int j=0; j<size-1; j++)
360     {
361         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
362         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
363
364         t.x = Xvmax;
365         //if(abs(p.x-s.x) > eps)
366             t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
367
368         if(s.x <= Xvmax && p.x <= Xvmax)            tri_clip[tri_clip_cnt++] = p;
369         else if(s.x < Xvmax && p.x > Xvmax)        tri_clip[tri_clip_cnt++] = t;
370         else if(s.x > Xvmax && p.x > Xvmax);
371         else if(s.x > Xvmax && p.x < Xvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
372     }
373     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
374     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
375     t.x = Xvmax;
376     //if(abs(p.x-s.x) > eps)
377         t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
378
379     if(s.x <= Xvmax && p.x <= Xvmax)            tri_clip[tri_clip_cnt++] = p;
380     else if(s.x < Xvmax && p.x > Xvmax)        tri_clip[tri_clip_cnt++] = t;
381     else if(s.x > Xvmax && p.x > Xvmax);
382     else if(s.x > Xvmax && p.x < Xvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
383
384     tri_save(i);
385 }
386 void tri_clip_judge_4(int i, int size)
387 {
388     if(size == 0)
389         return ;
390     tri_point s, p, t;
391     for(int j=0; j<size-1; j++)
392     {
393         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
394         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
395
396         t.y = Yvmax;
397         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
398
399         if(s.y <= Yvmax && p.y <= Yvmax)            tri_clip[tri_clip_cnt++] = p;
400         else if(s.y < Yvmax && p.y > Yvmax)        tri_clip[tri_clip_cnt++] = t;
401         else if(s.y > Yvmax && p.y > Yvmax);
402         else if(s.y > Yvmax && p.y < Yvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
403     }
404     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
405     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
406
407     t.y = Yvmax;
408     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
409
410     if(s.y <= Yvmax && p.y <= Yvmax)            tri_clip[tri_clip_cnt++] = p;
411     else if(s.y < Yvmax && p.y > Yvmax)        tri_clip[tri_clip_cnt++] = t;
412     else if(s.y > Yvmax && p.y > Yvmax);
413     else if(s.y > Yvmax && p.y < Yvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
414
415     tri_save(i);
416 }
417 void tri_clipping(int i)
418 {
419     tri_clip_judge_1(i, tri_view_num);
420     tri_clip_judge_2(i, tri_view_num);
421     tri_clip_judge_3(i, tri_view_num);
422     tri_clip_judge_4(i, tri_view_num);
423 }
424 void tri_save(int i)
425 {
426     tri_view_num = tri_clip_cnt;
427     for(int j=0; j<tri_view_num; j++)
428         tri_view[i][j] = tri_clip[j];
429     tri_clip_cnt=0;
430 }
431 void tri_drawing(int i, int size)
432 {
433     DrawLines_4(tri_view[i][size-1].x, tri_view[i][size-1].y, tri_view[i][0].x, tri_view[i][0].y);
434     for(int j=0; j<size-1; j++)
435         DrawLines_4(tri_view[i][j].x, tri_view[i][j].y, tri_view[i][j+1].x, tri_view[i][j+1].y);
436 }
437 void print(mat M)
438 {
439     for(int i=0; i<dimension; i++)
440     {
441         for(int j=0; j<dimension; j++)
442             printf("%.2lf ", M.m[i][j]);
443         printf("\n");
444     }
445     printf("\n");
446 }
447 void reset()
448 {
449     TM.reset_mat();
450     WVM.reset_mat();
451 }
452 void scale(float sx, float sy)
453 {
454     S.m[0][0] = sx; S.m[1][1] = sy;
455     TM = S * TM;
456     print(TM);
457 }
458 void rotate(float degree)
459 {
460     degree = degree * PI / 180.0;
461     R.m[0][0] = cos(degree); R.m[1][1] = cos(degree);
462     R.m[0][1] = -sin(degree); R.m[1][0] = sin(degree);
463     TM = R * TM;
464     print(TM);
465 }
466 void translate(float tx, float ty)
467 {
468     T.m[0][2] = tx; T.m[1][2] = ty;
469     TM =  T * TM;
470     print(TM);
471 }
472 void square()
473 {
474     square_point s0(-1, -1); squa_trans[squa_num].push_back(s0); squa_view[squa_num].push_back(s0);
475     square_point s1(1, -1);  squa_trans[squa_num].push_back(s1); squa_view[squa_num].push_back(s1);
476     square_point s2(1, 1);   squa_trans[squa_num].push_back(s2); squa_view[squa_num].push_back(s2);
477     square_point s3(-1, 1);  squa_trans[squa_num].push_back(s3); squa_view[squa_num].push_back(s3);
478
479     for(int j=0; j<squa_trans[squa_num].size(); j++)
480     {
481         float sx = TM.m[0][0] * squa_trans[squa_num][j].x + TM.m[0][1] * squa_trans[squa_num][j].y + TM.m[0][2];
482         float sy = TM.m[1][0] * squa_trans[squa_num][j].x + TM.m[1][1] * squa_trans[squa_num][j].y + TM.m[1][2];
483         squa_trans[squa_num][j].x = sx;
484         squa_trans[squa_num][j].y = sy;
485     }
486     squa_num++;;
487 }
488 void triangle()
489 {
490     tri_point t0(-1, -1); tri_trans[tri_num].push_back(t0); tri_view[tri_num].push_back(t0);
491     tri_point t1(1, -1);  tri_trans[tri_num].push_back(t1); tri_view[tri_num].push_back(t1);
492     tri_point t2(0, 1);   tri_trans[tri_num].push_back(t2); tri_view[tri_num].push_back(t2);
493
494     for(int j=0; j<3; j++)
495     {
496         float tx = TM.m[0][0] * tri_trans[tri_num][j].x + TM.m[0][1] * tri_trans[tri_num][j].y + TM.m[0][2];
497         float ty = TM.m[1][0] * tri_trans[tri_num][j].x + TM.m[1][1] * tri_trans[tri_num][j].y + TM.m[1][2];
498         tri_trans[tri_num][j].x = tx;
499         tri_trans[tri_num][j].y = ty;
500     }
501     tri_num++;
502 }
503
504 void view(float Xwmin, float Xwmax, float Ywmin, float Ywmax, float Xvmin, float Xvmax, float Yvmin, float Yvmax)
505 {
506     status="view";
507     DrawWindow();
508     //view_flag=0;
509     WVM.reset_mat();
510     TM.reset_mat();
511     translate(-Xwmin, -Ywmin);
512     WVM = T * WVM;
513     scale((Xvmax-Xvmin)/(Xwmax-Xwmin), (Yvmax-Yvmin)/(Ywmax-Ywmin));
514     WVM = S * WVM;
515     translate(Xvmin, Yvmin);
516     WVM = T * WVM;
517
518     status="square";
519     for(int i=0; i<squa_num; i++)
520     {
521         squa_view_num=4;
522         for(int j=0; j<squa_trans[i].size(); j++)
523         {
524             float sx = WVM.m[0][0] * squa_trans[i][j].x + WVM.m[0][1] * squa_trans[i][j].y + WVM.m[0][2];  //必须有中间变量
525             float sy = WVM.m[1][0] * squa_trans[i][j].x + WVM.m[1][1] * squa_trans[i][j].y + WVM.m[1][2];
526             squa_view[i][j].x = sx;        //储存view的数组必须和储存变换数组的不同
527             squa_view[i][j].y = sy;
528         }
529         square_clipping(i);
530         if(squa_view_num == 0)
531             continue;
532         square_drawing(i, squa_view_num);
533     }
534     cout << "squa_num : " << squa_num << endl;
535
536     status="triangle";
537     for(int i=0; i<tri_num; i++)
538     {
539         tri_view_num=3;
540         for(int j=0; j<tri_trans[i].size(); j++)
541         {
542             float sx = WVM.m[0][0] * tri_trans[i][j].x + WVM.m[0][1] * tri_trans[i][j].y + WVM.m[0][2];
543             float sy = WVM.m[1][0] * tri_trans[i][j].x + WVM.m[1][1] * tri_trans[i][j].y + WVM.m[1][2];
544             tri_view[i][j].x = sx;
545             tri_view[i][j].y = sy;
546         }
547         tri_clipping(i);
548         if(tri_view_num == 0)
549             continue;
550         tri_drawing(i, tri_view_num);
551     }
552     cout << "tri_num : " << tri_num << endl;
553
554     status ="none";
555
556 }
557 void clearData()
558 {
559
560 }
561 void clearScreen()
562 {
563
564 }
565 void initial()
566 {
567     T.reset_mat(); S.reset_mat(); R.reset_mat(); TM.reset_mat(); WVM.reset_mat(); M.reset_mat();
568     squa_num=0;
569     tri_num=0;
570     squa_view_num=4;
571     square_point clr;
572     tri_point clear;
573     for(int i=0; i<101; i++)
574         for(int j=0; j<101; j++)
575         {
576             squa_view[i].push_back(clr);
577             tri_view[i].push_back(clear);
578         }
579
580
581 }
582
583 void myKeyboard(unsigned char key, int x, int y)
584 {
585     cout << "KEYYYY" << endl;
586     switch(key) {
587     // Draw dots with ‘d‘ or ‘D‘
588     case ‘q‘:
589     case ‘Q‘:
590         //glutMouseFunc(Mymouse);
591           exit(0);
592           break;
593     }
594 }
595 void ReadInput(bool& IsExit)
596 {
597     float sx,sy,degree,tx,ty;
598     string command,comment;
599     cin>>command;
600     if (command=="scale")
601     {
602         cout<<command<<endl;
603         cin>>sx;
604         cin>>sy;
605         scale(sx,sy);
606     }
607     else if (command=="rotate")
608     {
609         cout<<command<<endl;
610         cin>>degree;
611         rotate(degree);
612     }
613     else if (command=="translate")
614     {
615         cout<<command<<endl;
616         cin>>tx;
617         cin>>ty;
618         translate(tx,ty);
619     }
620     else if (command=="reset")
621     {
622         cout<<command<<endl;
623         reset();
624     }
625     else if (command=="square")
626     {
627         cout<<command<<endl;
628         square();
629     }
630     else if (command=="triangle")
631     {
632         cout<<command<<endl;
633         triangle();
634     }
635     else if (command=="view")
636     {
637         cout<<command<<endl;
638         cin >> Xwmin >> Xwmax >> Ywmin >> Ywmax >> Xvmin >> Xvmax >> Yvmin >> Yvmax;
639         view(Xwmin, Xwmax, Ywmin, Ywmax, Xvmin, Xvmax, Yvmin, Yvmax);
640     }
641     else if (command=="clearData")
642     {
643         cout<<command<<endl;
644         clearData();
645     }
646     else if (command=="clearScreen")
647     {
648         cout<<command<<endl;
649         cout<<"Screen is cleared"<<endl;
650         clearScreen();
651     }
652     else if (command=="end")
653     {
654         cout<<command<<endl;
655         IsExit=true;
656         //exit(0);
657     }
658     else if (command=="#")
659     {
660         getline(cin, comment);
661     }
662 }
663
664
665 // Display function
666 void displayFunc(void){
667
668   freopen("hw2.in", "r", stdin);
669   bool IsExit;
670   IsExit=false;
671   // clear the entire window to the background color
672   glClear(GL_COLOR_BUFFER_BIT);
673   while (!IsExit)
674   {
675     glClearColor(0.0, 0.0, 0.0, 0.0);
676 //    redraw();
677   // draw the contents!!! Iterate your object‘s data structure!
678   // flush the queue to actually paint the dots on the opengl window
679     glFlush();
680     ReadInput(IsExit);
681   }
682  // infile.close();
683   //exit(0);
684 }
685
686
687 // Main
688 void main(int ac, char** av) {
689   initial();
690
691   int winSizeX, winSizeY;
692   string name;
693
694   if(ac == 3) {
695     winSizeX = atoi(av[1]);
696     winSizeY = atoi(av[2]);
697 //        cout<<"Done";
698   }
699   else { // default window size
700     winSizeX = 800;
701     winSizeY = 600;
702
703   }
704
705
706 //  cout<<"Please input file name:"<<endl;
707 //  cin>>name;
708 //  infile.open(name.c_str());
709  // exit(0);
710  // infile.open("inp3.txt");
711 // infile.open(av[1]);
712   width  = winSizeX;
713   height = winSizeY;
714
715   // initialize OpenGL utility toolkit (glut)
716   glutInit(&ac, av);
717
718   // single disply and RGB color mapping
719   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
720   glutInitWindowSize(winSizeX, winSizeY);      // set window size
721   glutInitWindowPosition(0, 0);                // set window position on screen
722   glutCreateWindow("Lab2 Window");       // set window title
723
724   // set up the mouse and keyboard callback functions
725    // register the keyboard action function
726   glutKeyboardFunc(myKeyboard);
727   // displayFunc is called whenever there is a need to redisplay the window,
728   // e.g., when the window is exposed from under another window or when the window is de-iconified
729   glutDisplayFunc(displayFunc); // register the redraw function
730
731   // set background color
732   glClearColor(0.0, 0.0, 0.0, 0.0);     // set the background to black
733   glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
734
735   // misc setup
736   glMatrixMode(GL_PROJECTION);  // setup coordinate system
737   glLoadIdentity();
738   gluOrtho2D(0, winSizeX, 0, winSizeY);
739   glShadeModel(GL_FLAT);
740   glFlush();
741   glutMainLoop();
742 }
743
744 void DrawLines_4(int x1, int y1, int x2, int y2) //判断画哪一种线
745 {
746     if(x1 >= x2)
747     {
748         if(y1 >= y2)
749         {
750             swap(x1, x2);
751             swap(y1, y2);
752             if((y2-y1) >= (x2-x1))
753                 drawLine2(x1, y1, x2, y2, 1);
754             else
755                 drawLine1(x1, y1, x2, y2, 1);
756         }
757         else
758         {
759             if((y2-y1) >= (x1-x2))
760                 drawLine3(x1, y1, x2, y2, 1);
761             else
762                 drawLine4(x2, y2, x1, y1, 1);
763         }
764     }
765     else
766     {
767         if(y2 >= y1)
768         {
769             if((y2-y1) <= (x2-x1))
770                 drawLine1(x1, y1, x2, y2, 1);
771             else
772                 drawLine2(x1, y1, x2, y2, 1);
773         }
774         else
775         {
776             if((y1-y2) <= (x2-x1))
777                 drawLine4(x1, y1, x2, y2, 1);
778             else
779                 drawLine3(x2, y2, x1, y1, 1);
780         }
781     }
782
783     glFlush();
784 }
785
786 // draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
787 void drawDot(int x, int y, float r, float g, float b)
788 {
789     glBegin(GL_POINTS);
790
791     // set the color of dot
792     glColor3f(r, g, b);
793
794     // invert height because the opengl origin is at top-left instead of bottom-left
795     glVertex2i(x , height - y);
796
797     glEnd();
798 }
799
800 // Draw line for dx>0 and dy>0
801 void drawLine1(int x1, int y1, int x2, int y2, bool xy_interchange) //0-45度
802 {
803     //cout << "Drawing Line1!" << endl;
804     int x = x1;
805     int y = y1;
806
807     int a = y2 - y1;
808     int b = x1 - x2;
809     int d = 2 * a + b;
810     int IncE = 2 * a;
811     int IncNE = 2 * (a + b);
812
813     while(x <= x2)
814     {
815         if(d <= 0)
816         {
817             x++;
818             d += IncE;
819         }
820         else
821         {
822             x++;
823             y++;
824             d += IncNE;
825         }
826
827         if(status == "square")
828             drawDot(x, height-y, 0.0, 10.0, 0.0);
829         //else if(judge_in(x, y))
830         else if(status == "triangle")
831             drawDot(x, height-y, 0.0, 0.0, 10.0);
832         else if(status == "view")
833             drawDot(x, height-y, 10.0, 0.0, 0.0);
834     }
835 }
836
837 // Draw line for dx>0 and dy<0
838 void drawLine2(int x1, int y1, int x2, int y2, bool xy_interchange) //45-90度
839 {
840     //cout << "Drawing Line2!" << endl;
841     //转换为0-45度的情况
842     swap(x2, y2);
843     swap(x1, y1);
844
845     int x = x1;
846     int y = y1;
847
848     int a = y2 - y1;
849     int b = x1 - x2;
850     int d = 2 * a + b;
851     int IncE = 2 * a;
852     int IncNE = 2 * (a + b);
853
854     while(x <= x2)
855     {
856         if(d <= 0)
857         {
858             x++;
859             d += IncE;
860         }
861         else
862         {
863             x++;
864             y++;
865             d += IncNE;
866         }
867
868         if(status == "square")
869             drawDot(y, height-x, 0.0, 10.0, 0.0);
870         //else if(judge_in(y, x))
871         else if(status == "triangle")
872             drawDot(y, height-x, 0.0, 0.0, 10.0);
873         else if(status == "view")
874             drawDot(y, height-x, 10.0, 0.0, 0.0);
875     }
876 }
877
878 // Draw line for dx<0 and dy>0
879 void drawLine3(int x1, int y1, int x2, int y2, bool xy_interchange) //90-135度
880 {
881     //cout << "Drawing Line3!" << endl;
882     swap(x2, y2);
883     swap(x1, y1);
884     y1 = -y1;
885     y2 = -y2;
886     int x = x1;
887     int y = y1;
888
889     int a = y2 - y1;
890     int b = x1 - x2;
891     int d = 2 * a + b;
892     int IncE = 2 * a;
893     int IncNE = 2 * (a + b);
894
895     while(x <= x2)
896     {
897         if(d <= 0)
898         {
899             x++;
900             d += IncE;
901         }
902         else
903         {
904             x++;
905             y++;
906             d += IncNE;
907         }
908
909         if(status == "square")
910             drawDot(-y, height-x, 0.0, 10.0, 0.0);
911         //else if(judge_in(-y, x))
912         else if(status == "triangle")
913             drawDot(-y, height-x, 0.0, 0.0, 10.0);
914         else if(status == "view")
915             drawDot(-y, height-x, 10.0, 0.0, 0.0);
916     }
917 }
918
919 // Draw line for dx<0 and dy>0
920 void drawLine4(int x1, int y1, int x2, int y2, bool xy_interchange) //135-180度
921 {
922     //cout << "Drawing Line4!" << endl;
923     y1 = -y1;
924     y2 = -y2;
925     int x = x1;
926     int y = y1;
927
928     int a = y2 - y1;
929     int b = x1 - x2;
930     int d = 2 * a + b;
931     int IncE = 2 * a;
932     int IncNE = 2 * (a + b);
933
934     while(x <= x2)
935     {
936         if(d <= 0)
937         {
938             x++;
939             d += IncE;
940         }
941         else
942         {
943             x++;
944             y++;
945             d += IncNE;
946         }
947
948         if(status == "square")
949             drawDot(x, height+y, 0.0, 10.0, 0.0);
950         //else if(judge_in(x, -y))
951         else if(status == "triangle")
952             drawDot(x, height+y, 0.0, 0.0, 10.0);
953         else if(status == "view")
954             drawDot(x, height+y, 10.0, 0.0, 0.0);
955     }
956 }
时间: 2024-10-11 18:15:41

OpenGL多边形变换和裁剪的相关文章

OpenGL法向量变换

OpenGL光照开启时,法向量用于决定特定顶点或面上接受到光照的多少.光照处理过程作用于观察坐标空间,因此,模型对象坐标系的法向量也需要使用GL_MODELVIEW矩阵变换到观察坐标系. 然而,法向量与顶点的变换方式不同.我们不能够简单将GL_MODELVIEW矩阵与法线相乘.设想顶点(0,0,0)的法向量(1,0,0).如果GL_MODELVIEW矩阵为沿Y轴移动2个单位,顶点坐标将为(0,2,0).不过,法线依旧为相同的(1,0,0),而不是(1,2,0). 为了理解法向量如何变换到观察空间

OpenGL学习——变换——绕x轴来回旋转的木板

学习OpenGL的变换. Local Space => World Space => View Space => Clip Space => Screen Space ModelMatrix ViewMatrix ProjectionMatrix   :   Orthographic   Perspective GLM: OpenGL Mathematics 变换效果: 初始化与渲染代码: RectFall.h #ifndef RectFall_h #define RectFall

SharpGL学习笔记(七) OpenGL的变换总结

笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对"将三维体正确的显示在屏幕上指定位置"这样的操作都无法完成. OpenGL变换包括计算机图形学中最基本的三维变换,即几何变换.投影变换.裁剪变换.视口变换,以及针对OpenGL的特殊变换概念理解和用法,如相机模拟.矩阵堆栈等,这些基础是开始真正走进三维世界无法绕过的基础. 所以笔者在前面花了

第02课 OpenGL 多边形

你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形.读完了这一课,你会学到如何在空间放置模型,并且会知道深度缓存的概念. 第一课中,我教您如何创建一个OpenGL窗口.这一课中,我将教您如何创建三角形和四边形.我们讲使用来创建GL_TRIANGLES一个三角形,GL_QUADS来创建一个四边形. 在第一课代码的基础上,我们只需在DrawGLScene()过程中增加代

&lt;五&gt;初探opengl,变换我们的图形

这节主要是对我们的纹理矩形进行一下变换,例如缩放,旋转,中间需要运用到一些线性代数的东西这里就不再阐述,因为我自己也不怎么会...我们直接介绍代码怎么写吧. 矩阵的相乘是从右往左读取的,这点提醒一下自己. GLM 代码中大部分的矩阵处理信息都是通过glm库来处理的,全称OPENGL MATHEMATICS ,去这里下载,把glm文件夹放到工程的include下即可.代码i引入文件库 #include <glm/glm.hpp> #include <glm/gtc/matrix_trans

Cyrus-Beck裁剪算法及OpenGL实践

恩..接着就是Cyrus-Beck算法.这个算法比之前的Cohen-Sutherland算法厉害,处理任意凸多边形对线段的裁剪.自然,这个算法也比Cohen-Sutherland算法复杂不少. 首先,是线段与多边形相交的情况: 我们把定义向量c = (C - A),而线段AC是射线A + ct的一部分.那么t取0和1就是线段AC.我们将射线与多边形的每条边求出相交时的t.取tin = max(0, tin),tout = max(tout, 1).最终会获得一个区间[tin,tout]就是经多边

OpenGL变换

概述 OpenGL变换矩阵 实例:GL_MODELVIEW矩阵 实例:GL_PROJECTION矩阵 概述 OpenGL管线中,在光栅化操作之前,包括顶点位置与法线向量的几何数据经顶点操作与图元装配操作进行变换. 模型坐标 它是模型对象的局部坐标系,同时也是任何变换之前模型对象的初始位置与朝向.为了变换模型对象,可以使用glRotatef().glTranslatef().glScalef(). 观察坐标 它由模型坐标乘以GL_MODELVIEW矩阵产生.在OpenGL中,可以使用GL_MODE

三维图像技术与OpenGL基础理论

英文原文:3D Graphics with OpenGL Basic Theory 中文译文:三维图像技术与OpenGL基础理论 1. 计算机图像硬件 1.1 GPU(图像处理单元) 如今,计算机拥有用来专门做图像处理显示的GPU模块,拥有独立的图像处理储存(显存). 1.2 像素和画面 任何图像显示都是基于栅格的格式.一个栅格既是一张二维的像素直角坐标网.像素具有两个属性:颜色和位置.颜色通常使用RGB(红绿蓝)来表示,典型的有用8位或者24位二进制位(真彩色)表示一种颜色.位置则用坐标(x,

OpenGL教程翻译 第十八课 漫反射光(Diffuse Lighting)

OpenGL教程翻译 第十七课 环境光(Ambient Lighting) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 环境光和漫反射光的主要不同是,漫反射光的计算需要依靠光线方向而环境光完全忽略了它!当只有环境光时整个场景被均等照亮.漫反射光会使物体面对光的部分比背对光的部分更加明亮. 此外漫反射光还增加了一点新的计算,光线的入射角决定了表面的亮度.通过下面的图片来演示这个概念: 让我们假设两条光线的强度是一样的,而唯一不一