OpenGL 画线

0x00

1
2
3
4
5
6
7
8
9
实验二:(2学时)
一、实验目的:
利用鼠标、键盘,菜单等方式对图元进行交互操作
二、实验内容:
1、用鼠标拖动画直线,线段终点始终跟随鼠标移动;
2、使用菜单界面修改直线的颜色;
3、利用键盘控制直线在屏幕上移动;
三、实现效果及步骤(或流程)
四、创新设计和实现方法

0x01

  • 直接上代码,具体可参考书本

    P459 鼠标函数、P462 键盘函数、P471 菜单功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include "stdafx.h"
#include <GL/glut.h>
GLsizei winWidth = 400, winHeight = 300;
class scrPt {
public:
GLint x, y;
};
scrPt endPt1, endPt2; //起点以及终点
GLfloat r=0.0, g=0.0, b=0.0; //颜色代码
bool flag;
int ptCtr = 0;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);//背景设置为白色
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 400.0, 0.0, 300.0);
}
void displayfcn(void){
}
void winReshapeFcn(GLint newWidth, GLint newHeight) { //窗体大小变化时刷新
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
glFlush();
}
void lineSegment(scrPt endPt1, scrPt endPt2) //画线函数
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(r, g, b);
glBegin(GL_LINES);
glVertex2i(endPt1.x, endPt1.y);
glVertex2i(endPt2.x, endPt2.y);
glEnd();
glFlush();
}
void mainMenu(GLint selectOptional) { //改变颜色菜单
switch (selectOptional)
{
case 1:
r = 255;
g = b = 0;
lineSegment(endPt1, endPt2);
break;
case 2:
g = 255;
r = b = 0;
lineSegment(endPt1, endPt2);
break;
case 3:
b = 255;
r = g = 0;
lineSegment(endPt1, endPt2);
break;
}
}
void ployline1(GLint button, GLint action, GLint xMouse, GLint yMouse) { //确定起始终点坐标

if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (ptCtr == 0) {
r = g = b = 0.0;
endPt1.x = xMouse;
endPt1.y = winHeight - yMouse;
ptCtr = 1;
}
else if (ptCtr == 1) {
lineSegment(endPt1, endPt2);
ptCtr = 0;
}
}
}
void ployline2(GLint xMouse, GLint yMouse) { //持续获取鼠标位置
if (ptCtr == 1) {
endPt2.x = xMouse;
endPt2.y = winHeight - yMouse;
lineSegment(endPt1, endPt2);
}
}
void keyBoardeve(GLint specialKey, GLint xMouse, GLint yMouse) { //键盘控制
switch (specialKey)
{
case GLUT_KEY_UP:
flag = endPt1.y > endPt2.y ? true : false;
if (flag && endPt2.y>=winHeight) {
endPt2.y = 0-(endPt1.y - endPt2.y);
endPt1.y = 0;
lineSegment(endPt1, endPt2);
}
else if (!flag && endPt1.y >= winHeight) {
endPt1.y = 0-(endPt2.y - endPt1.y);
endPt2.y = 0;
lineSegment(endPt1, endPt2);
}
else {
endPt1.y += 10;
endPt2.y += 10;
lineSegment(endPt1, endPt2);
}
break;
case GLUT_KEY_DOWN:
flag = endPt1.y > endPt2.y ? true : false;
if (flag && endPt1.y <= 0) {
endPt1.y = winHeight + (endPt1.y - endPt2.y);
endPt2.y = winHeight;
lineSegment(endPt1, endPt2);
}
else if (!flag && endPt2.y <=0) {
endPt2.y = winHeight + (endPt2.y - endPt1.y);
endPt1.y = winHeight;
lineSegment(endPt1, endPt2);
}
else {
endPt1.y -= 10;
endPt2.y -= 10;
lineSegment(endPt1, endPt2);
}
break;
case GLUT_KEY_LEFT:
flag = endPt1.x < endPt2.x ? true : false;
if (flag && endPt2.x <= 0) {
endPt2.x = winWidth + (endPt2.x - endPt1.x);
endPt1.x = winWidth;
lineSegment(endPt1, endPt2);
}
else if (!flag && endPt1.x <= 0) {
endPt1.x = winWidth + (endPt1.x - endPt2.x);
endPt2.x = winWidth;
lineSegment(endPt1, endPt2);
}
else {
endPt1.x -= 10;
endPt2.x -= 10;
lineSegment(endPt1, endPt2);
}
break;
case GLUT_KEY_RIGHT:
flag = endPt1.x < endPt2.x ? true : false;
if (flag && endPt1.x >= winWidth) {
endPt1.x = 0 - (endPt2.x - endPt1.x);
endPt2.x = 0;
lineSegment(endPt1, endPt2);
}
else if (!flag && endPt2.x >= winWidth) {
endPt2.x = 0 - (endPt1.x - endPt2.x);
endPt1.x = 0;
lineSegment(endPt1, endPt2);
}
else {
endPt1.x += 10;
endPt2.x += 10;
lineSegment(endPt1, endPt2);
}
break;
default:
break;
}
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayfcn);
glutReshapeFunc(winReshapeFcn);
glutPassiveMotionFunc(ployline2);
glutMouseFunc(ployline1);
glutSpecialFunc(keyBoardeve);
glutCreateMenu(mainMenu);
glutAddMenuEntry("red", 1);
glutAddMenuEntry("green", 2);
glutAddMenuEntry("blue", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON); //右键启动菜单
glutMainLoop();
}
  • 最终效果

两点确定直线,右键唤出菜单

颜色变换

0x02

封面出处:http://simpledesktops.com/browse/desktops/2019/jan/19/lion/

Author: ronething
Link: https://blog.ronething.cn/20171110-opengl.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.