计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制
VS+OpenGL绘图环境及基本图形绘制1、熟悉OpenGL的主要功能;2、掌握OpenGL的绘图流程和原理;3、掌握OpenGL核心函数的使用;4、熟悉OpenGL基本图形元素的绘制函数。二.实验内容1、如预备知识所述,创建一个OpenGL工程,修改第一个程序中的Display()函数,如下:该程序是在窗口中画两条线,分别用黄色和红色绘制。如上所述,OpenGL是一个状态机,glBegin(UI
实验一 VS+OpenGL绘图环境及基本图形绘制
一、实验目的
- 熟悉OpenGL的主要功能;
- 掌握OpenGL的绘图流程和原理;
- 掌握OpenGL核心函数的使用;
- 熟悉OpenGL基本图形元素的绘制函数。
二、实验内容
- 如预备知识所述,创建一个OpenGL工程,修改第一个程序中的Display()函数,如下:
void Display(void)
{
glClear (GL_COLOR_BUFFER_BIT); //清除缓存
glColor3f (1.0f, 1.0f, 0.0f); //设置颜色为黄色
//设置第一根线的两个端点,请注意:OpenGL坐标系的原点是在屏幕左下角
glVertex2f(10.0f, 50.0f);
glVertex2f(110.0f, 50.0f);
glColor3f (1.0f, 0.0f, 0.0f); //设置颜色为红色
//设置第二根线的两个端点
glVertex2f(110.0f, 50.0f);
glVertex2f(110.0f, 150.0f);
glEnd(); //画线结束
glFlush ();
}
该程序是在窗口中画两条线,分别用黄色和红色绘制。如上所述,OpenGL是一个状态机,glBegin(UINT State)可以设定如下状态:
GL_POINTS 画点
GL_LINES 画线,每两个顶点(Vertex)为一组
GL_LINE_STRIP 画线,把若干个顶点顺次连成折线
GL_LINE_LOOP 画线,把若干个顶点顺次连成封闭折线
GL_TRIANGLES 画三角形,每三个顶点为一组
GL_QUADS 画四边形,每四个顶点为一组
GL_POLYGON 画多边形
还有GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUAD_STRIP 等等。另外,程序可以有多组glBegin()、glEnd()并列的形式,如:
... ...
glBegin(GL_LINES);
......
glEnd();
glBegin(GL_QUADS);
... ...
glEnd();
... ...
要求:利用OpenGL库函数绘制基本图形,输出绘制结果。
- 绘制函数,通过设置观察矩形和视口,使得曲线在窗口的显示效果如下图所示。
- 利用OpenGL函数绘制圆弧和心脏线。
圆弧通过其中心c,外接圆的半径R,以及开始的角度a和它展开的角度b来表示,函数可以表示为:
void drawArc(Point2 center, float radius, float startAngle, float sweep)
心脏线要求平铺屏幕窗口,并创建菜单,通过菜单设定心脏线的大小(K值决定大小),通过鼠标动作改变心脏线的颜色。心脏线的极坐标形式为:
参考代码:
恐龙平铺屏幕窗口polyline.cpp
菜单GlutMenu.cpp
三、实验设计思路
1. 创建一个OpenGL工程,修改初始化代码Display函数,glBegin(GL_LINES)开始画线;glColor3f ()设置颜色;glVertex2f()设置第一根线的两个端点。从而得到两条颜色及位置不同的线段。
2.修改Display函数,glBegin(GL_LINE_STRIP);开始画线,把若干个顶点顺次连成折线glColor3f(0.0f, 0.0f, 0.0f);设置颜色,利用for循环描点glVertex2f(i, exp(-i) * cos(2 * 3.14 * i));函数。再修改Initial函数中gluOrtho2D(0.0, 4.0, -1.0, 1.0);的X与Y轴显示区域。
3. 圆弧通过其中心c,外接圆的半径R,以及开始的角度a和它展开的角度b来表示;对心脏线进行绘制,创建菜单以控制心脏线的大小,用鼠标左键控制菜单弹出,K设置了五个心脏线大小。通过鼠标右键来控制颜色,glColor3f(red/256.0+0.5, green/256.0+0.5, blue/256.0+0.5);设置随机数,最后通过glViewport调节视口,来实现了一个5*5的平铺屏幕窗口效果。
四、实验代码
1.
#include <gl/glut.h>
void Initial(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口背景颜色为白色
glMatrixMode(GL_PROJECTION); //设置投影参数
glLoadIdentity();
gluOrtho2D(0.0, 200.0, 0.0, 200.0);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT); //清除缓存
glBegin(GL_LINES); //开始画线
glColor3f(1.0f, 1.0f, 0.0f); //设置颜色为黄色
//设置第一根线的两个端点,请注意:OpenGL坐标系的原点是在屏幕左下角
glVertex2f(10.0f, 50.0f);
glVertex2f(110.0f, 50.0f);
glColor3f(1.0f, 0.0f, 0.0f); //设置颜色为红色
//设置第二根线的两个端点
glVertex2f(110.0f, 50.0f);
glVertex2f(110.0f, 150.0f);
glEnd(); //画线结束
glFlush();
}
void main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化窗口的显示模式
glutInitWindowSize(400, 400); //设置窗口的尺寸
glutInitWindowPosition(100, 120); //设置窗口的位置
glutCreateWindow("矩形"); //创建一个名为矩形的窗口
glutDisplayFunc(Display); //设置当前窗口的显示回调函数
Initial(); //完成窗口初始化
glutMainLoop(); //启动主GLUT事件处理循环
// return 0;
}
2.
#include <gl/glut.h>
#include<math.h>
void Initial(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口背景颜色为白色
glMatrixMode(GL_PROJECTION); //设置投影参数
glLoadIdentity();
gluOrtho2D(0.0, 4.0, -1.0, 1.0);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_STRIP);
glColor3f(0.0f, 0.0f, 0.0f);
for (float i = 0; i <= 4; i = i + 0.01)
{
glVertex2f(i, exp(-i) * cos(2 * 3.14 * i));
}
glEnd();
glFlush();
}
void main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化窗口的显示模式
glutInitWindowSize(400, 400); //设置窗口的尺寸
glutInitWindowPosition(100, 120); //设置窗口的位置
glutCreateWindow("矩形"); //创建一个名为矩形的窗口
glutDisplayFunc(Display); //设置当前窗口的显示回调函数
Initial(); //完成窗口初始化
glutMainLoop(); //启动主GLUT事件处理循环
// return 0;
}
3.1
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
GLuint startList;
void init(void)
{
GLUquadricObj* qobj;
startList = glGenLists(1);
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); /* 只画边缘 */
gluQuadricNormals(qobj, GLU_NONE);/*不算NORMAL(顶点的方向)*/
glNewList(startList, GL_COMPILE);/*只编译DISPLAY LIST不绘制*/
gluPartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0);/* 第一个参数是A quadric object,然后内圆半径为0.0,外圆半径为1.0,z轴向分割片数,最后两个参数是圆弧的起始角和结束角 */
glEndList();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(1.0, 1.0, 0.0);
glCallList(startList);
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.5, 2.5, -2.5 * (GLfloat)h / (GLfloat)w,
2.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
else
glOrtho(-2.5 * (GLfloat)w / (GLfloat)h,
2.5 * (GLfloat)w / (GLfloat)h, -2.5, 2.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(300, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
3.2
#include <windows.h>
#include<iostream>
#include <GL/glut.h>
#include <cmath>
#define PI 3.1415926
#define RED 1
#define GREEN 2
#define BLUE 3
#define WHITE 4
//初始化OpenGL场景
float red = 1.0, blue = 1.0, green = 1.0;
float K = 1;
void myinit(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); //将背景置成黑色
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-12.0, 12.0, -12.0, 12.0);
}
//用户的绘图过程
void mydisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glColor3f(1.0, 0.0, 0.0);
glColor3f(red / 256.0 + 0.5, green / 256.0 + 0.5, blue / 256.0 + 0.5);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++)
{
glViewport(i * 64, j * 64, 100, 100);
glBegin(GL_LINE_LOOP);
for (float x = 0; x < 2 * 3.14; x = x + 0.1)
{
glVertex2f((1 + cos(x)) * cos(x) * K, (1 + cos(x)) * sin(x) * K);
}
glEnd();
}
}
glFlush();
}
void myMouse(int button, int state, int x, int y) {
if (state == GLUT_DOWN)
{
if (button == GLUT_RIGHT_BUTTON)
{
red = rand() / 128;
blue = rand() / 128;
green = rand() / 128;
}
else if (button == GLUT_RIGHT_BUTTON)
{
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); // Red
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
}
}
void processMenuEvents_two(int option) {
switch (option)
{
case 1:K = 1; break;
case 2:K = 2; break;
case 3:K = 3; break;
case 4:K = 4; break;
case 5:K = 5; break;
default:
break;
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(400, 400);
glutCreateWindow("心脏线");
myinit();
glutDisplayFunc(mydisplay);
glutIdleFunc(mydisplay);//空闲回调函数
glutMouseFunc(myMouse);
glutCreateMenu(processMenuEvents_two);
glutAddMenuEntry("one", 1);
glutAddMenuEntry("two", 2);
glutAddMenuEntry("three", 3);
glutAddMenuEntry("four", 4);
glutAddMenuEntry("five", 5);
glutAttachMenu(GLUT_LEFT_BUTTON);
glutMainLoop();
}
五、实验结果及心得体会
1.
2.
3
此次实验,学会了基本的VS+OpenGL绘图环境及基本图形绘制,了解了OpenGL的主要功能以及绘图流程和原理。实现了OpenGL核心函数的使用以及基本图形元素的绘制函数。还实现了鼠标交互等功能。通过本次实验绘制了不同的函数图像,对今后的学习也有了较大的帮助。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)