// 在此处引用程序要求的附加头文件:
#include "5DG_Window.h"
// 在此处加入程序要求的库到链接器中:
#pragma comment(lib, "opengl32.lib") // 链接时查找OpenGL32.lib
#pragma comment(lib, "glu32.lib") // 链接时查找glu32.lib
#pragma comment(lib, "glaux.lib") // 链接时查找glaux.lib
#pragma comment(lib, "glut32.lib") // 链接时查找glut32.lib
//在此处定义程序中用到的宏
#define NO_OBJ 0
#define OBJ1 1 // 第一个物体的ID
#define OBJ2 2 // 第二个物体的ID
#define OBJ3 3 // 第三个物体的ID
#define FEED_BUFF_SIZE 50000 // 定义反馈缓冲区的大小
#define BUFFER_LENGTH 64 // 定义检选缓冲区的大小
#define MAXTEXTURE 6 // 定义纹理数组的大小
// 在此处定义全局变量:
GL_Window* OGL_window;
Keys* OGL_keys;
GLuint texture[MAXTEXTURE]; // 纹理数组,保存纹理名字
GLuint base; // 显示字体列表的ID
// 在此处定义用户变量:
BOOL mouseDown; // 判断鼠标按键是否按下
BOOL showObjInfo; // 是否允计显示信息
BOOL pKeyH; // 用于判断'H'是否按下
GLint mouse_x,mouse_y; // 鼠标坐标值
GLint middleObj; // 在屏幕中间的物体的ID
GLint selectedObj; // 当前鼠标选中的物体ID
BOOL mouseInCenter; // 鼠标是否在场景中央区域
RECT bRect; // 用于存放反馈出的物体方框的数值
GLint objTriangleNum[3]; // 用于存放反馈出的物体的三角形的个数
GLdouble wx,wy,wz; // 用于存放在OPENGL中转化后的鼠标坐标
GLdouble wx1,wy1,wz1; // 同上,用于存放鼠标拖动物体时物体坐标
GLfloat angle_y1,angle_y2,angle_y3; // 用于控制三个物体的自转
GLfloat posl[]={400.0f, 400.0f, 200.0f, 1.0f};
GLfloat amb[] ={0.3f, 0.3f, 0.3f ,1.0f};
GLfloat spec[]={1.0f, 1.0f,1.0f, 1.0f};
float shininess=100.0f;
// 绘制要被检选的物体
void DrawObjects(void)
{
// 判断鼠标是否在边长为50的正方形内
float tempx,tempy;
tempx = mouse_x-WIDTH/2;
tempy = HEIGHT/2-mouse_y;
if (tempx>-50.0f && tempx<50.0f && tempy>-50.0f && tempy<50.0f)
mouseInCenter = TRUE;
else
mouseInCenter = FALSE;
// 启用光照
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// 初始化名称堆栈
glInitNames();
glPushName(0);
// 绘制第一个物体
glPushMatrix();
// 设置是否将OBJ1放置在屏幕中央
// 鼠标选中OBJ1时,清除屏幕中央物体
// 鼠标在屏幕中央松开时,将物体放置在屏幕中央
if (selectedObj == OBJ1)
{
if (mouseDown)
{
middleObj = NO_OBJ;
}
else if (mouseInCenter)
{
middleObj = OBJ1;
}
}
// 用当前元素0BJ1替换栈顶元素
glLoadName(OBJ1);
// 往反馈缓冲区中插入一个用户定义的标记0BJ1
glPassThrough((GLfloat)OBJ1);
// 设置物体的位置(跟随鼠标/在屏幕中央/在物体原处)
if (selectedObj == OBJ1 && mouseDown)
glTranslatef(wx1, wy1, wz1);
else if (middleObj == OBJ1)
glTranslatef(0.0f, 0.0f, wz1);
else
glTranslatef(-2.0f, 1.2f, wz1);
// 设置物体旋转(物体被选中且鼠标未按下时旋转)
glRotatef(angle_y1, 0.0f, 1.0f, 0.0f);
if (selectedObj==OBJ1 && !mouseDown)
{
angle_y1 += 1.0f;
}
// 设置物体颜色
if (selectedObj==OBJ1 || middleObj==OBJ1)
glColor3f(0.4f, 0.4f, 0.4f);
else
glColor3f(0.2f, 0.2f, 0.2f);
// 绘制茶壶
glutSolidTeapot(0.5f);
glPopMatrix();
// 绘制第二个物体
glPushMatrix();
// 设置是否将OBJ1放置在屏幕中央
if (selectedObj==OBJ2)
{
if (mouseDown)
{
middleObj = NO_OBJ;
}
else if (mouseInCenter)
{
middleObj = OBJ2;
}
}
glLoadName(OBJ2);
glPassThrough((GLfloat)OBJ2);
// 设置物体的位置
if (selectedObj == OBJ2 && mouseDown)
glTranslatef(wx1, wy1, wz1);
else if (middleObj == OBJ2)
glTranslatef(0.0f, 0.0f, wz1);
else
glTranslatef(-2.0f, 0.0f, wz1);
// 设置物体旋转
glRotatef(angle_y2, 0.0f, 1.0f, 0.0f);
if (selectedObj==OBJ2&&!mouseDown)
angle_y2+=1.0f;
if (selectedObj==OBJ2 || middleObj==OBJ2)
glColor3f(1.0f, 1.0f, 1.0f);
else
glColor3f(0.3f, 0.3f, 0.3f);
// 设置多面体的纹理
glBindTexture(GL_TEXTURE_2D,texture[3]);
glEnable(GL_TEXTURE_2D);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
// 绘制正十二面体
glScalef(0.3, 0.3, 0.3);
glutSolidDodecahedron();
// 关闭纹理映射
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
// 绘制第三个物体
glPushMatrix();
// 设置是否将OBJ3放置在屏幕中央
if (selectedObj == OBJ3)
{
if (mouseDown)
{
middleObj = NO_OBJ;
}
else if (mouseInCenter)
{
middleObj = OBJ3;
}
}
glLoadName(OBJ3);
glPassThrough((GLfloat)OBJ3);
// 设置物体的位置
if (selectedObj==OBJ3 && mouseDown)
glTranslatef(wx1, wy1, wz1);
else if (middleObj == OBJ3)
glTranslatef(0.0f, 0.0f, wz1);
else
glTranslatef(-2.0f, -1.2f, wz1);
// 设置物体旋转
glRotatef(angle_y3, 0.0f, 1.0f, 0.0f);
if (selectedObj==OBJ3 && !mouseDown)
angle_y3+=1.0f;
// 设置物体颜色
if (selectedObj==OBJ3 || middleObj==OBJ3)
glColor3f(0.4f, 0.4f, 0.4f);
else
glColor3f(0.2f, 0.2f, 0.2f);
// 绘制球
glutSolidSphere(0.5f, 20, 20);
glPopMatrix();
// 关闭光照
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 1.0f);
}
// 检选函数
void ProcessSelection(void)
{
GLuint selectBuff[BUFFER_LENGTH]; // 定义检选缓冲区
GLint viewport[4]; // 用于存放视口信息
glSelectBuffer(BUFFER_LENGTH, selectBuff); // 设置检选缓冲区
glRenderMode(GL_SELECT); // 设置为检选模式
glGetIntegerv(GL_VIEWPORT, viewport); // 获得当前视口数据
glMatrixMode(GL_PROJECTION); // 切换到投影矩阵模式
glPushMatrix(); // 保存当前投影矩阵
glLoadIdentity(); // 重置投影矩阵
gluPickMatrix(mouse_x, viewport[3] - mouse_y, 2, 2, viewport); // 定义矩形检选区域
// 设置透视投影
gluPerspective(30, (float)OGL_window->init.width/(float)OGL_window->init.height, 0.1, 100);
glMatrixMode(GL_MODELVIEW); // 切换到模型视图矩阵
DrawObjects(); // 调用DrawObjects()绘制物体,但它并不会被光栅化
glMatrixMode(GL_PROJECTION);
glPopMatrix(); // 恢复原投影矩阵
glMatrixMode(GL_MODELVIEW);
glRenderMode(GL_RENDER); // 设置光栅模式为渲染模式
if (selectBuff[3]!=OBJ1 && selectBuff[3]!=OBJ2 && selectBuff[3]!=OBJ3) // 无物体被选中时
selectedObj = NO_OBJ; // 设置selectedObj为NO_OBJ
else if(!mouseDown) // 有物体被选中且鼠标不是按下时
selectedObj = selectBuff[3]; // 设置selectedObj为被选中的物体的ID
}
// 反馈函数,其参数为当前选中的物体ID
void MakeSelection(int nChoice)
{
GLfloat feedBackBuff[FEED_BUFF_SIZE]; // 定义反馈缓冲区
int size,j,count,i; // 定义要用到的循环变量
int triangleNum=0; // 用来保存三角形的个数
// 初始化bRect
bRect.right = bRect.bottom = -9999.0f;
bRect.left = bRect.top = 9999.0f;
glFeedbackBuffer(FEED_BUFF_SIZE, GL_2D, feedBackBuff); // 建立反馈缓冲区
glRenderMode(GL_FEEDBACK); // 设置光栅模式为反馈模式
DrawObjects(); // 在反馈模式下面绘制物体
size = glRenderMode(GL_RENDER); // 设置光栅模式为渲染模式,返回写入反馈缓冲区的大小
i = 0;
while (i < size) // 遍历反馈缓冲区,读取数据
{
if (feedBackBuff[i] == GL_PASS_THROUGH_TOKEN) // 若标记为用户定义的标记
{
if (feedBackBuff[i+1] == (GLfloat)nChoice) // 判断是不是选中的物体
{
i += 2;
// 读取两个物体标记间的物体数据
while (i < size && feedBackBuff[i] != GL_PASS_THROUGH_TOKEN)
{
// 判断标记是否为多边形类型
if (feedBackBuff[i] == GL_POLYGON_TOKEN)
{
// 读取多边形顶点个数
count = (int)feedBackBuff[++i];
// 计算三角形个数
if (count == 3)
triangleNum++;
i++;
// 开始读取接下来的各个顶点信息
OpenGL拣选与反馈
3星 · 超过75%的资源 需积分: 9 66 浏览量
2009-12-07
14:23:57
上传
评论
收藏 160KB RAR 举报
xinyuanzhang
- 粉丝: 0
- 资源: 1
最新资源
- keil2 + proteus + 8051.exe
- 1961ee27df03bd4595d28e24b00dde4e_744c805f7e4fb4d40fa3f695bfbab035_8(1).c
- mediapipe-0.9.0.1-cp37-cp37m-win-amd64.whl.zip
- windows注册表编辑工具
- mediapipe-0.9.0.1-cp37-cp37m-win-amd64.whl.zip
- 校园通行码预约管理系统20240522075502
- 车类型数据集6250张VOC+YOLO格式.zip
- The PyTorch implementation of STGCN.STGCN-main.zip
- 092300108.cpp
- 车类型数据集6000张VOC+YOLO格式.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈