OpenGL 基础图形绘制与投影变换

1. 参数定义的House

2. a flurry of filled rectangles

3. Sierpinski曲线

含有鼠标和键盘响应函数onmouse和onkeyboard。

/************************************************************************/
/* CreateTime:2013-2-18
**Author:@Rachel Zhang
**Discription: Draw Parameter House, Flurry and Sierpinski
**3rd-party:OpenGL*/
/************************************************************************/

#include "GL/glut.h"
#include "stdlib.h"
#include <iostream>
using namespace std;
#define screenHeight 480

class GLintPoint{
public:
 GLint x, y;
};

// Create a number between 0 and m(a number which will be given)
// the input m must be less than 32767 according to P49 in <Computer Graphics Using OpenGL>
int random(int m)
{
 return rand()%m;
}

void drawDot (GLint x, GLint y)
{
 glPointSize(3);
 glBegin(GL_POINTS);
 glVertex2i(x,y);
 glEnd();
}

typedef struct
{
 GLfloat r, g, b;
} GLfloatRGBColour;

GLfloatRGBColour colour[8] = { {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f},
{0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};

void setPenColour(GLfloatRGBColour newColour)
{
 glColor3f(newColour.r, newColour.g, newColour.b);
}

/************************************************************************/
/*                                Draw Functions                                      */
/************************************************************************/
void parameterizedHouse(GLintPoint peak, GLint width, GLint height)
 // the top of house is at the peak; the size of house is given
 //  by height and width
{
 glBegin(GL_LINE_LOOP);
 glVertex2i(peak.x,            peak.y);  // draw shell of house
 glVertex2i(peak.x + width / 2, peak.y - 3 * height /8);
 glVertex2i(peak.x + width / 2,  peak.y -    height);
 glVertex2i(peak.x - width / 2, peak.y -    height);
 glVertex2i(peak.x - width / 2, peak.y - 3 * height /8); 
 glEnd();
}

void drawFlurry(int num, int Width, int Height)
 // draw num random rectangles in a Width by Height rectangle
{
 for (int i = 0; i < num; i++)
 {
  GLint x1 = random(Width);   // place corner randomly
  GLint y1 = random(Height);
  GLint x2 = random(Width);   // pick the size so it fits
  GLint y2 = random(Height);
  GLfloat lev = random(10)/10.0;  // random value, in range 0 to 1
  glColor3f(lev,lev,lev);   // set the gray level
  glRecti(x1, y1, x2, y2);   // draw the rectangle
 }
 glFlush();

void drawSierpinski(GLintPoint corner[3])
{
 int i, index, tcolour=0;
 GLintPoint point;
 point = corner[random(3)];
 drawDot(point.x, point.y);

for (i = 0; i < 1000; i++)
 {
  index = random(3);
  point.x = (point.x + corner[index].x)/2;
  point.y = (point.y + corner[index].y)/2; 
  tcolour = (++tcolour)%7;      // col = (col + 1) mod 7;
  setPenColour(colour[tcolour]);
  drawDot(point.x, point.y);
 }
}

/************************************************************************/
/*                        Mouse Listener and keyboard Listener                    */
/************************************************************************/
void myMouse(int button, int state, int x, int y)
{
 static GLintPoint corners[3];
 static int numCorners;

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
 {
  corners[numCorners].x = x;
  corners[numCorners].y = screenHeight - y - 1;
  if (++numCorners == 3)
  {
   drawSierpinski(corners);
   numCorners = 0;
  }
 }
 else if (button==GLUT_RIGHT_BUTTON)
  glClear(GL_COLOR_BUFFER_BIT);
 glFlush();
}

void onKeyBoard(unsigned char key,int mousex, int mousey)
{
 switch (key)
 {
 case 'q':
  exit(0);
 case 'r':
  static GLintPoint corners[3];
  for (int i=0;i<3;i++)
  {
   corners[i].x = random(640);
   corners[i].y = random(screenHeight);
  }
  drawSierpinski(corners);
 default:
  break;
 }
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/2a86919cb766d096b2be1a22d2f3294d.html