实验二代码
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#define MAXN 1000
#define SIZE 500
/*
键盘1,2,3,4对应 白,红,绿,蓝
键盘Q,W,E,R,T对应 线段,矩形,三角形,四边形,五边形
可以通过鼠标右键设置上述属性,同时带有清除功能
shitf+鼠标右键可以选择图形并高亮
点击空白处即可恢复
*/
struct graphic {
int type;
GLfloat color[4];
GLfloat point[5][2];
GLenum mode;
}list[MAXN];
struct Now {
//count 当前图形数量 type 当前绘制什么图形
GLint count, hitsmax, hitsnow, type, last[MAXN], lastcount;//last和lastcount分别用来记录点击的图片和图片数(高亮)
GLenum mode;
GLfloat color[4], point[5][2], w, h;//w,h窗口宽高
}now;//现在选择模式
//设置菜单1,绘制什么图形
//now.hitsnow记录当前绘制了几个点 所以要初始化
void setMenu1(int value) {
if (value == 1) {
printf("123");
now.type = 1;
now.hitsmax = 2;
now.hitsnow = 0;
}
else if (value == 2) {
now.type = 2;
now.hitsmax = 2;
now.hitsnow = 0;
}
else if (value == 3) {
now.type = 3;
now.hitsmax = 3;
now.hitsnow = 0;
}
else if (value == 4) {
now.type = 4;
now.hitsmax = 4;
now.hitsnow = 0;
}
else if (value == 5) {
now.type = 5;
now.hitsmax = 5;
now.hitsnow = 0;
}
else {
now.count = 0;//为了防止drawObject在清除缓存后重新绘制图形(每次调用都会绘制),所以将此设置为0
printf("123");
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
printf("123");
}
}
//填充方式
void menu1(int value) {
if (value == 1)
now.mode = GL_FILL;
else if (value == 2) {
now.mode = GL_LINE;
}
}
//菜单二 颜色
void menu2(int value) {
//为了区分高亮,所以设置为0.7
if (value == 1) {
now.color[0] = 0.7;
now.color[1] = 0.7;
now.color[2] = 0.7;
}
else if (value == 2) {
now.color[0] = 0.5;
now.color[1] = 0;
now.color[2] = 0;
}
else if(value==3)
{
now.color[0] = 0;
now.color[1] = 0.5;
now.color[2] = 0;
}
else if (value == 4) {
now.color[0] = 0;
now.color[1] = 0;
now.color[2] = 0.5;
}
}
void init()
{
//菜单及菜单回调
int menuBack1, menuBack2;
now.hitsnow = now.count = now.lastcount = 0;
now.type = 1;
now.hitsmax = 2;
glClearColor(0.0, 0.0, 0.0, 0.0);
now.color[0] = 0.7; now.color[1] = 0.7; now.color[2] = 0.7;
now.mode = GL_FILL;
menuBack1 = glutCreateMenu(menu1);
glutAddMenuEntry("填充", 1);
glutAddMenuEntry("勾勒", 2);
menuBack2 = glutCreateMenu(menu2);
glutAddMenuEntry("白色", 1);
glutAddMenuEntry("红色", 2);
glutAddMenuEntry("绿色", 3);
glutAddMenuEntry("蓝色", 4);
glutCreateMenu(setMenu1);
glutAddMenuEntry("创建线段(默认绘制线段)", 1);
glutAddMenuEntry("创建矩形", 2);
glutAddMenuEntry("创建三角形", 3);
glutAddMenuEntry("创建四边形", 4);
//glutAddMenuEntry("创建五边形", 5);
glutAddMenuEntry("清屏",6);
glutAddSubMenu("选择模式(默认填充)", menuBack1);
glutAddSubMenu("改变颜色(默认白色)", menuBack2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
/*
void drawObjects(GLenum mode)
{
if(mode == GL_SELECT) glLoadName(1);
glColor3f(1.0, 0.0, 0.0);
glRectf(-0.5, -0.5, 1.0, 1.0);
if(mode == GL_SELECT) glLoadName(2);
glColor3f(0.0, 0.0, 1.0);
glRectf(-1.0, -1.0, 0.5, 0.5);
}
*/
void drawObjects(GLenum mode) {
GLint i;
for (i = 1; i <= now.count; i++) {
if (mode == GL_SELECT)
glLoadName(i);
glColor3fv(list[i].color);
glPolygonMode(GL_FRONT_AND_BACK, list[i].mode);
if (list[i].type == 1)
{
glBegin(GL_LINES);
glVertex2fv(list[i].point[0]);
glVertex2fv(list[i].point[1]);
glEnd();
}
else if (list[i].type == 2) {
glRectfv(list[i].point[0], list[i].point[1]);
}
else if (list[i].type == 3) {
glBegin(GL_POLYGON);
glVertex2fv(list[i].point[0]);
glVertex2fv(list[i].point[1]);
glVertex2fv(list[i].point[2]);
glEnd();
}
else if (list[i].type == 4) {
glBegin(GL_POLYGON);
glVertex2fv(list[i].point[0]);
glVertex2fv(list[i].point[1]);
glVertex2fv(list[i].point[2]);
glVertex2fv(list[i].point[3]);
glEnd();
}
else {
glBegin(GL_POLYGON);
glVertex2fv(list[i].point[0]);
glVertex2fv(list[i].point[1]);
glVertex2fv(list[i].point[2]);
glVertex2fv(list[i].point[3]);
glVertex2fv(list[i].point[4]);
glEnd();
}
}
}
//高亮
void change(int i) {
now.lastcount++;
now.last[now.lastcount] = i;
if (list[i].color[1] == 0.0)
list[i].color[0] = 1.0;
else {
list[i].color[0] = 1.0;
list[i].color[1] = 1.0;
list[i].color[2] = 1.0;
}
}
//用now.lastcount 记录点击数量,同时用此恢复高亮,此时通过调用drawObject函数绘制颜色
void recover() {
for (; now.lastcount > 0; now.lastcount--) {
if (list[now.last[now.lastcount]].color[1] == 0.0)
list[now.last[now.lastcount]].color[0] = 0.5;
else {
list[now.last[now.lastcount]].color[0] = 0.5;
list[now.last[now.lastcount]].color[1] = 0.5;
list[now.last[now.lastcount]].color[2] = 0.5;
}
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
drawObjects(GL_RENDER);
glFlush();
}
/* processHits prints out the contents of the
* selection array.
*/
void processHits(GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLint names, *ptr;
printf("hits = %d\n", hits);
ptr = (GLint *)buffer;
/*for (i = 0; i < hits; i++) {
names = *ptr;
ptr+=3;
for (j = 0; j < names; j++) {
if(*ptr==1) printf ("red rectangle\n");
else printf ("blue rectangle\n");
ptr++;
}
printf ("\n");
}*/
if (hits == 0) {
recover();
return;
}
//根据点击绘制高亮
for (i = 0; i < hits; i++) {
names = *ptr;
ptr += 3;
for (j = 0; j < names; j++) {
change(*ptr);
ptr++;
}
}
}
void mouse(int button, int state, int x, int y)
{
GLuint selectBuf[SIZE];
GLint hits, i, j;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT && button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
recover();
glSelectBuffer(SIZE, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), 5.0, 5.0, viewport);
gluOrtho2D(0, now.w, 0, now.h);
drawObjects(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
hits = glRenderMode(GL_RENDER);
processHits(hits, selectBuf);
}
else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
now.point[now.hitsnow][0] = (GLdouble)x;
now.point[now.hitsnow][1] = (GLdouble)(viewport[3] - y);
now.hitsnow++;
if (now.hitsnow == now.hitsmax) {
now.count++;
/*for (i = 0; i <= 3; i++) {
list[now.count].color[i] = now.color[i];
for (j = 0; j < 2; j++) {
list[now.count].point[i][j] = now.point[i][j];
}
}*/
for (i = 0; i < 3; i++) {
list[now.count].color[i] = now.color[i];
}
for (i = 0; i < now.hitsmax; i++) {
for (j = 0; j < 2; j++) {
list[now.count].point[i][j] = now.point[i][j];
}
}
list[now.count].type = now.type;
list[now.count].mode = now.mode;
now.hitsnow = 0;
}
}
/* if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
glGetIntegerv (GL_VIEWPORT, viewport);
glSelectBuffer (SIZE, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),
5.0, 5.0, viewport);
gluOrtho2D (-2.0, 2.0, -2.0, 2.0);
drawObjects(GL_SELECT);
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glFlush ();
hits = glRenderMode (GL_RENDER);
processHits (hits, selectBuf);
glutPostRedisplay();
}*/
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, 0, h);
now.w = w;
now.h = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case '1':
now.color[0] = 0.7;
now.color[1] = 0.7;
now.color[2] = 0.7;
break;
case '2':
now.color[0] = 0.5;
now.color[1] = 0;
now.color[2] = 0;
break;
case '3':
now.color[0] = 0;
now.color[1] = 0.5;
now.color[2] = 0;
break;
case '4':
now.color[0] = 0;
now.color[1] = 0;
now.color[2] = 0.5;
break;
case 'q':
now.type = 1;
now.hitsmax = 2;
now.hitsnow = 0;
break;
case 'w':
now.type = 2;
now.hitsmax = 2;
now.hitsnow = 0;
break;
case 'e':
now.type = 3;
now.hitsmax = 3;
now.hitsnow = 0;
break;
case 'r':
now.type = 4;
now.hitsmax = 4;
now.hitsnow = 0;
break;
case 't':
now.type = 5;
now.hitsmax = 5;
now.hitsnow = 0;
break;
}
}
/* Main Loop */
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}