📄 选择与反馈.cpp
字号:
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
#include<GL\glaux.h>
#pragma comment(lib,"opengl32")
#pragma comment(lib,"glu32")
#pragma comment(lib,"glaux")
#define MAXOBJS 10000
#define MAXSELECT 100
#define MAXFEED 300
#define SOLID 1
#define LINE 2
#define POINT 3
static void InitObjects(GLint num);
static void Init(void);
static void CALLBACK Resize(int width,int height);
static void Render(GLenum mode);
static DoSelect(GLint x,GLint y);
static void RecolorTri(GLint h);
static void DeleteTri(GLint h);
static void GrowTri(GLint h);
void CALLBACK Mouse_left(AUX_EVENTREC* event);
void CALLBACK Mouse_middle(AUX_EVENTREC* event);
void CALLBACK Mouse_right(AUX_EVENTREC* event);
static void CALLBACK Paint(void);
static void PaintZoom(GLint x,GLint y);
static void DumpFeedbackVert(GLint *i,GLint n);
static void PaintFeedback(GLint n);
static void DoFeedback(void);
static void CALLBACK Key_LEFT(void);
static void CALLBACK Key_RIGHT(void);
static void CALLBACK Key_Z(void);
static void CALLBACK Key_z(void);
static void CALLBACK Key_f(void);
static void CALLBACK Key_d(void);
static void CALLBACK Key_l(void);
GLint windW,windH;
GLuint selectBuf[MAXSELECT];
GLfloat feedBuf[MAXFEED];
GLint vp[4];
float zRotation=90.0;
float zoom=1.0;
GLint objectCount;
GLint numObjects;
struct object{
float v1[2];
float v2[2];
float v3[2];
float color[3];
}objects[MAXOBJS];
GLenum linePoly=GL_FALSE;
static void InitObjects(GLint num)
{
GLint i;
float x,y;
if(num>MAXOBJS)
num=MAXOBJS;
if(num<1)num=1;
objectCount=num;
srand((unsigned int)time(NULL));
for(i=0;i<num;i++)
{
x=(rand()%300)-150;
y=(rand()%300)-150;
objects[i].v1[0]=x+(rand()%50)-25;
objects[i].v2[0]=x+(rand()%50)-25;
objects[i].v3[0]=x+(rand()%50)-25;
objects[i].v1[1]=y+(rand()%50)-25;
objects[i].v2[1]=y+(rand()%50)-25;
objects[i].v3[1]=y+(rand()%50)-25;
objects[i].color[0]=((rand()%100)+50)/150.0;
objects[i].color[1]=((rand()%100)+50)/150.0;
objects[i].color[3]=((rand()%100)+50)/150.0;
}
}
static void Init(void)
{
numObjects=10;
InitObjects(numObjects);
glGetIntegerv(GL_VIEWPORT,vp);
}
static void CALLBACK Resize(int width,int height)
{
windW=(GLint)width;
windH=(GLint)height;
}
static void Render(GLenum mode)
{
GLint i;
for(i=0;i<objectCount;i++)
{
if(mode==GL_SELECT)glLoadName(i);
glColor3fv(objects[i].color);
glBegin(GL_POLYGON);
glVertex2fv(objects[i].v1);
glVertex2fv(objects[i].v2);
glVertex2fv(objects[i].v3);
glEnd();
}
}
static GLint DoSelect(GLint x,GLint y)
{
GLint hits;
glSelectBuffer(MAXSELECT,selectBuf);
(void)glRenderMode(GL_SELECT);
glInitNames();
glPushName((GLuint)~0);
glPushMatrix();
glViewport(0,0,windW,windH);
glGetIntegerv(GL_VIEWPORT,vp);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix(x,windH-y,4,4,vp);
gluOrtho2D(-175,175,-175,175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom,zoom,zoom);
glRotatef(zRotation,0,0,1);
Render(GL_SELECT);
glPopMatrix();
hits=glRenderMode(GL_RENDER);
if(hits<=0)return -1;
return selectBuf[(hits-1)*4+3];
}
static void RecolorTri(GLint h)
{
objects[h].color[0]=((rand()%100)+50)/150.0;
objects[h].color[1]=((rand()%100)+50)/150.0;
objects[h].color[2]=((rand()%100)+50)/150.0;
}
static void DeleteTri(GLint h)
{
objects[h]=objects[objectCount-1];
objectCount--;
}
static void GrowTri(GLint h)
{
float v[2];
float *oIdV;
GLint i;
v[0]=objects[h].v1[0]+objects[h].v2[0]+objects[h].v3[0];
v[1]=objects[h].v1[1]+objects[h].v2[1]+objects[h].v3[1];
v[0]/=3;
v[1]/=3;
for(i=0;i<3;i++)
{
switch(i)
{
case 0:
oIdV=objects[h].v1;
break;
case 1:
oIdV=objects[h].v2;
break;
case 2:
oIdV=objects[h].v3;
break;
}
oIdV[0]=1.5*(oIdV[0]-v[0])+v[0];
oIdV[1]=1.5*(oIdV[1]-v[1])+v[1];
}
}
void CALLBACK Mouse_left(AUX_EVENTREC *event)
{
GLint mouseX,mouseY;
GLint hit;
mouseX=event->data[AUX_MOUSEX];
mouseY=event->data[AUX_MOUSEY];
hit=DoSelect((GLint)mouseX,(GLint)mouseY);
if(hit!=-1)RecolorTri(hit);
//return GL_FALSE;
}
void CALLBACK Mouse_middle(AUX_EVENTREC *event)
{
GLint mouseX,mouseY;
GLint hit;
mouseX=event->data[AUX_MOUSEX];
mouseY=event->data[AUX_MOUSEY];
hit=DoSelect((GLint)mouseX,(GLint)mouseY);
if(hit!=-1)GrowTri(hit);
//return GL_FALSE;
}
void CALLBACK Mouse_right(AUX_EVENTREC *event)
{
GLint mouseX,mouseY;
GLint hit;
mouseX=event->data[AUX_MOUSEX];
mouseY=event->data[AUX_MOUSEY];
hit=DoSelect((GLint)mouseX,(GLint)mouseY);
if(hit!=-1)DeleteTri(hit);
//return GL_FALSE;
}
static void CALLBACK Paint(void)
{
glPushMatrix();
glViewport(0,0,windW,windH);
glGetIntegerv(GL_VIEWPORT,vp);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-175,175,-175,175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom,zoom,zoom);
glRotatef(zRotation,0,0,1);
Render(GL_RENDER);
glPopMatrix();
}
static void PaintZoom(GLint x,GLint y)
{
glPushMatrix();
glViewport(0,0,windW,windH);
glGetIntegerv(GL_VIEWPORT,vp);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix(x,windH-y,4,4,vp);
gluOrtho2D(-175,175,-175,175);
glMatrixMode(GL_COLOR_BUFFER_BIT);
glScalef(zoom,zoom,zoom);
glRotatef(zRotation,0,0,1);
Render(GL_RENDER);
glPopMatrix();
}
static void DumpFeedbackVert(GLint *i,GLint n)
{
GLint index;
index=*i;
if(index+7>n)
{
*i=n;
printf(" ???\n");
return;
}
printf("(%g%g%g),color=(%4.2f%4.2f%4.2f)\n",
feedBuf[index],
feedBuf[index+1],
feedBuf[index+2],
feedBuf[index+3],
feedBuf[index+4],
feedBuf[index+5]);
index+=7;
*i=index;
}
static void PaintFeedback(GLint n)
{
GLint i;
GLint verts;
printf("Feedback results(%d floats):\n",n);
for(i=0;i<n;i++)
{
switch((GLint)feedBuf[i])
{
case GL_POLYGON_TOKEN:
printf("Polygon");
i++;
if(i<n)
{
verts=(GLint)feedBuf[i];
i++;
printf(":%d vettices",verts);
}
else verts=0;
printf("\n");
while(verts)
{
DumpFeedbackVert(&i,n);
verts--;
}
i--;
break;
case GL_LINE_TOKEN:
printf("Line:\n");
i++;
DumpFeedbackVert(&i,n);
DumpFeedbackVert(&i,n);
i--;
break;
case GL_LINE_RESET_TOKEN:
printf("Line Reset:\n");
i++;
DumpFeedbackVert(&i,n);
DumpFeedbackVert(&i,n);
i--;
break;
default:
printf("%9.2f\n",feedBuf[i]);
break;
}
}
if(i==MAXFEED)
printf("...\n");
printf("\n");
}
static void DoFeedback(void)
{
GLint x;
glFeedbackBuffer(MAXFEED,GL_3D_COLOR,feedBuf);
(void)glRenderMode(GL_FEEDBACK);
glPushMatrix();
glViewport(0,0,windW,windH);
glGetIntegerv(GL_VIEWPORT,vp);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-175,175,-175,175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom,zoom,zoom);
glRotatef(zRotation,0,0,1);
Render(GL_FEEDBACK);
glPopMatrix();
x=glRenderMode(GL_RENDER);
if(x==-1)
x=MAXFEED;
PaintFeedback((GLint)x);
}
static void CALLBACK Key_LEFT(void)
{
zRotation+=0.5;
}
static void CALLBACK Key_RIGHT(void)
{
zRotation-=0.5;
}
static void CALLBACK Key_Z(void)
{
zoom/=0.75;
}
static void CALLBACK Key_z(void)
{
zoom*=0.75;
}
static void CALLBACK Key_f(void)
{
DoFeedback();
}
static void CALLBACK Key_d(void)
{
GLint mouseX,mouseY;
auxGetMouseLoc(&mouseX,&mouseY);
PaintZoom((GLint)mouseX,(GLint)mouseY);
}
static void CALLBACK Key_l(void)
{
linePoly=!linePoly;
if(linePoly)
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
void main(int argc,char **argv)
{
GLenum type;
windW=300;
windH=300;
auxInitPosition(0,0,windW,windH);
type=AUX_RGB|AUX_SINGLE;
auxInitDisplayMode(type);
if(auxInitWindow("Select Test")==GL_FALSE)
auxQuit();
Init();
auxExposeFunc((AUXEXPOSEPROC)Resize);
auxReshapeFunc((AUXRESHAPEPROC)Resize);
auxKeyFunc(AUX_LEFT,Key_LEFT);
auxKeyFunc(AUX_RIGHT,Key_RIGHT);
auxKeyFunc(AUX_Z,Key_Z);
auxKeyFunc(AUX_z,Key_z);
auxKeyFunc(AUX_f,Key_f);
auxKeyFunc(AUX_d,Key_d);
auxKeyFunc(AUX_l,Key_l);
auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,Mouse_left);
//auxMouseFunc(AUX_MIDDLEBUTTON,AUX_MOUSEDOWN,Mouse_middle);
auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSEDOWN,Mouse_right);
auxMainLoop(Paint);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -