实验一、OpenGL直线、圆的绘制
1、实验目的
1)了解OpenGL 图形库的功能和结构;
2)学习了解OpenGL 程序的基本结构,及常用函数;
3)学习使用OpenGL 绘制基本图形(线、圆);
2、实验内容
1)使用OpenGL 编写一个简单的C++程序,使该程序能够绘制出直线。
2 )使用OpenGL 编写一个简单的C++程序,使该程序能够绘制出圆。
3、实验过程
1)在系统上配置好OpenGL的环境(头文件,库文件,和链接库文件);
2)使用Visual V++6.0 新建一个C++文档,并创建相应的工程;
3)在文档中引入OpenGL的头文件,编辑代码实现鼠标拖动画直线,画圆。
4、实验结果
可单击鼠标左键,然后拖动鼠标画出两条直线,并同时画出圆;
可单击鼠标右键,然后拖动鼠标画出两个圆,并同时画出直线。结果截图:
1.鼠标左键主要控制绘制的直线:
2.鼠标右键主要控制绘制的圆:
5、实验代码
1.#include
2.#include
3.
4.// GLint pNum = 0;
5.GLint px1, py1, px2, py2, cx, cy, r;
6.GLint winWidth=600, winHeight=600;
7.
8.//////////////////画直线////////////
9.void Draw_Bresenham(int pStartx,int pStarty,int
pEndx,int pEndy)
10.{//用Bresenham算法画直线
11. int i;
12.
13. if(pStartx==pEndx)
14. {
15. //为竖线
16. if(pStarty<=pEndy)
17. {
18. for(i=pStarty;i<=pEndy;i++)
19. glVertex2f(pStartx,i);
20. }
21. else
22. {
23. for(i=pEndy;i<=pStarty;i++)
24. glVertex2f(pStartx,i);
25. }
26.
27. return;
28. }
29.
30. //为横线
31. if(pStarty==pEndy)
32. {
33. if(pStartx<=pEndx)
34. {
35. for(i=pStartx;i<=pEndx;i++)
36. glVertex2f(i,pStarty);
37. }
38. else
39. {
40. for(i=pEndx;i<=pStartx;i++)
41. glVertex2f(i,pStarty);
42. }
43.
44. return;
45. }
46.
47. //为斜线
48. float m=(pEndy-pStarty)*1.0/(pEndx-pStartx);
49. float p;
50.
51. p=2*m-1;
52. if(m>0 && m<=1)
53. {
54. if(pStartx 55. { 56. while(pStartx<=pEndx) 57. { 58. glVertex2f(pStartx++,pStarty); 59. if(p>=0) 60. { 61. p+=2*m-2; 62. pStarty++; 63. } 64. else 65. p+=2*m; 66. } 67. } 68. else 69. { 70. while(pEndx<=pStartx) 71. { 72. glVertex2f(pEndx++,pEndy); 73. if(p>=0) 74. { 75. p+=2*m-2; 76. pEndy++; 77. } 78. else 79. p+=2*m; 80. } 81. } 82. 83. return; 84. } 85. 86. p=-2*m-1; 87. if(m<0 && m>=-1) 88. { 89. if(pStartx 90. { 91. while(pStartx<=pEndx) 92. { 93. glVertex2f(pStartx++,pStarty); 94. if(p>=0) 95. { 96. p+=-2*m-2; 97. pStarty--; 98. } 99. else 100. p+=-2*m; 101. } 102. } 103. else 104. { 105. while(pEndx<=pStartx) 106. { 107. glVertex2f(pEndx++,pEndy); 108. if(p>=0) 109. { 110. p+=-2*m-2; 111. pEndy--; 112. } 113. else 114. p+=-2*m; 115. } 116. } 117. 118. return; 119. } 120. 121. p=2/m-1; 122. if(m>1) 123. { 124. if(pStarty 125. { 126. while(pStarty<=pEndy) 127. { 128. glVertex2f(pStartx,pStarty++); 129. if(p>=0) 130. { 131. p+=2/m-2; 132. pStartx++; 133. } 134. else 135. p+=2/m; 136. } 137. } 138. else 139. { 140. while(pEndy<=pStarty) 141. { 142. glVertex2f(pEndx,pEndy++); 143. if(p>=0) 144. { 145. p+=2/m-2; 146. pEndx++; 147. } 148. else 149. p+=2/m; 150. } 151. } 152. 153. return; 154. } 155. 156. p=-2/m-1; 157. if(pStarty 158. { 159. while(pStarty<=pEndy) 160. { 161. glVertex2f(pStartx,pStarty++); 162. if(p>=0) 163. { 164. p+=-2/m-2; 165. pStartx--; 166. } 167. else 168. p+=-2/m; 169. } 170. } 171. else 172. { 173. while(pEndy<=pStarty) 174. { 175. glVertex2f(pEndx,pEndy++); 176. if(p>=0) 177. { 178. p+=-2/m-2; 179. pEndx--; 180. } 181. else 182. p+=-2/m; 183. } 184. } 185.} 186. 187.//////////////////画圆//////////// 188./////////其他象限绘制 189.void CirclePoints(int x,int y){ 190. //第1象限 191. glVertex2f(x,y); 192. glVertex2f(y,x); 193. //第2象限 194. glVertex2f(-x,y); 195. glVertex2f(-y,x); 196. //第3象限 197. glVertex2f(-y,-x); 198. glVertex2f(-x,-y); 199. //第4象限 200. glVertex2f(x,-y); 201. glVertex2f(y,-x); 202. 203.} 204.//////////中点算法画圆 205.void DrawCircle(int cx,int cy,int radis){ 206. 207. glPushMatrix(); 208. glTranslatef(cx,cy,0); 209.glPointSize(1); 210.glColor3f(0.5f, 0.5f, 1.0f); 211.glBegin(GL_POINTS); 212. 213. int x,y; 214. double p; 215. x=0; 216. y=radis; 217. p=1.25-radis; 218. while(x<=y+1) 219. { 220. CirclePoints(x,y); 221. x++; 222. if(p>=0) 223. { 224. y--; 225. p+=2.0*(x-y)+5; 226. } 227. else 228. p+=2*x+3; 229. } 230.glEnd(); 231.glPopMatrix(); 232.} 233. 234. 235.//////////绘制坐标轴 236.void DrawOx(){ 237.glColor3f(0.95, 0.7, 0.8); 238.glPointSize(1); 239.glBegin(GL_LINES); 240.glVertex2f(-winWidth/2,0); 241.glVertex2f(winWidth/2,0); 242.glVertex2f(0,winHeight/2); 243.glVertex2f(0,-winHeight/2); 244.glEnd(); 245.} 246. 247.//////////显示函数 248.void Display(){ 249. ////////GL_COLOR_BUFFER_BIT(用背景颜色填充) 250. glClear(GL_COLOR_BUFFER_BIT); 251. 252.DrawOx(); 253. 254.glColor3f(0.0,0.0,1.0); 255. 256.glBegin(GL_POINTS); 257.//BresenhamLine(px1, py1, px2, py2); 258.Draw_Bresenham(px1, py1, px2, py2); 259.glEnd(); 260.glBegin(GL_POINTS); 261.Draw_Bresenham(py1, px1, py2, px2); 262.glEnd(); 263. //glBegin(GL_LINES); 264.//glVertex2f(px1,py1); 265.//glVertex2f(px2,py2); 266.//glVertex2f(py1,px1); 267.//glVertex2f(py2,px2); 268.//glEnd(); 269. 270. DrawCircle(cx,cy,r); 271. DrawCircle(cy,cx,r); 272. 273. ///交换缓冲区 274.glutSwapBuffers(); 275.//glFlush();// 刷新绘图命令 276.} 277. 278. 279.// 设置渲染状态(听起来满下人,实际上很简单)280.void SetupRC(void) 281.{ 282.//清除颜色(这里为黑色,为了方便找画的那个点),可以理解成背景颜色 283.//和glColor4f(1.0f, 0.0f, 0.0f,1.0f)一样,所有参数都在0.0到1.0之间,后缀f是表示参数是浮点型的284.//最后的那个1.0f是透明度,0.0f表示全透明,1.0f 是完全不透明 285.glClearColor(1.0f, 1.0f, 1.0f,1.0f); 286.} 287. 288.// 当绘制的窗口大小改变时重新绘制,使绘制的图形同 比例变化, 289.//几乎所有OpenGL程序中的这个函数都是一样的,所以,放心大胆的拷贝吧 290.void ChangeSize(int w, int h) 291.{ 292.winWidth = w; 293.winHeight = h; 294.// 设置观察视野为窗口大小(用FLASH里面的话来说应该叫设置摄象机视野) 295.glViewport(0,0,w,h); 296.// 重置坐标系统,指定设置投影参数 297.glMatrixMode(GL_PROJECTION); 298.///////调用单位矩阵,去掉以前的投影参数设置299.glLoadIdentity(); 300. //////设置投影参数 301.gluOrtho2D(-w/2,w/2,-h/2,h/2); 302.} 303. 304./////////////////鼠标点击 305.void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse){ 306.if(button==GLUT_LEFT_BUTTON && action==GLUT_DOWN){ 307.px1 = xMouse - winWidth/2; 308.py1 = winHeight/2 - yMouse; 309.} 310. if(button==GLUT_LEFT_BUTTON && action==GLUT_UP){ 311.px2 = xMouse - winWidth/2; 312.py2 = winHeight/2 - yMouse; 313.glutPostRedisplay(); 314.} 315.if(button==GLUT_RIGHT_BUTTON && action==GLUT_DOWN){ 316.cx=xMouse-winWidth/2; 317.cy=winHeight/2-yMouse; 318.} 319.} 320.////////////////鼠标移动 321.void MouseMove(GLint xMouse,GLint yMouse){ 322.px2 = xMouse - winWidth/2; 323.py2 = winHeight/2 - yMouse; 324. r=sqrt(pow((xMouse-winWidth/2-cx),2)+pow((winHeig ht/2-yMouse-cy),2)); 325.glutPostRedisplay(); 326.} 327. 328.// 主函数 329.int main(int argc, char* argv[]) 330.{ 331.glutInit(&argc, argv); 332.//设置显示模式 333.glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 334.//设置窗口大小像素 335.glutInitWindowSize(600, 600); 336.////设置窗口出现在屏幕的位置 337.glutInitWindowPosition(300,160); 338.//建立一个叫OpenGL的窗口 339.glutCreateWindow("OpenGL-Line"); 340. 341.//调用函数Display进行绘制 342.glutDisplayFunc(Display); 343. //////调用鼠标移动函数 344. //glutPassiveMotionFunc(PassiveMouseMove); 345.glutMotionFunc(MouseMove); 346.//////调用鼠标点击函数 347.glutMouseFunc(MousePlot); 348. 349.//如果窗口大小改变则调用函数ChangeSize重新进行绘制 350.glutReshapeFunc(ChangeSize); 351.//清屏 352.SetupRC(); 353.//循环绘制 354.glutMainLoop(); 355. 356.return 0; 357.}