OpenGl在3D中绘制鼠标选择框2D

以下代码实现:当空格键按下时,点击鼠标进行框选,屏幕中出现选择框。

//绘制3D选框
void xxxRender3D::DrawSelectionRectangle3D(){
	if (m_bSpaceKeyDown){
		if (m_bLBDown && m_bMouseMove){
			glm::vec3 firPoint = m_RectSelPt1;//鼠标的第一个点
			glm::vec3 secPoint = m_RectSelPt2;//鼠标的第二个点
			if (abs(firPoint.x - secPoint.x) > 1e-3)
			{
				glDisable(GL_LIGHTING);

				//绘制选择框
				glColor3f(1, 0, 0);

				//glm::vec3 viewdir = m_pDataManager->m_pCamera3D->GetDirection();
				//glm::vec3 offset = glm::vec3(1000 * viewdir.x, 1000 * viewdir.y, 1000 * viewdir.z);

				glm::vec3 upLeftPt, upRightPt, downLeftPt, downRightPt;

				/*upLeftPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(firPoint.x, firPoint.y,0.0)) + offset;
				upRightPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(secPoint.x, firPoint.y,0.0)) + offset;
				downRightPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(secPoint.x, secPoint.y,0.0)) + offset;
				downLeftPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(firPoint.x, secPoint.y, 0.0)) + offset;*/
				upLeftPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(firPoint.x, firPoint.y, 0.0));
				upRightPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(secPoint.x, firPoint.y, 0.0));
				downRightPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(secPoint.x, secPoint.y, 0.0));
				downLeftPt = m_pDataManager->m_pCamera3D->ScreenToWorld(glm::vec3(firPoint.x, secPoint.y, 0.0));


				GLDrawLine(upLeftPt, upRightPt);
				GLDrawLine(upRightPt, downRightPt);
				GLDrawLine(downRightPt, downLeftPt);
				GLDrawLine(downLeftPt, upLeftPt);
				glEnable(GL_LIGHTING);
			}
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的示例代码,它使用OpenGL和Open3D库来实现鼠标拖动画矩形,并选择点云数据的感兴趣区域。您可以根据自己的需求进行修改和扩展。 ```python import glfw from OpenGL.GL import * from OpenGL.GLU import * import open3d as o3d import numpy as np # 定义顶点坐标、颜色和法向量 vertices = np.array([ [-0.5, -0.5, 0.0], [0.5, -0.5, 0.0], [0.5, 0.5, 0.0], [-0.5, 0.5, 0.0] ], dtype=np.float32) colors = np.array([ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 0.0] ], dtype=np.float32) normals = np.array([ [0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0] ], dtype=np.float32) # 定义顶点索引 indices = np.array([ [0, 1, 2], [2, 3, 0] ], dtype=np.uint32) # 创建一个窗口 def create_window(width, height): if not glfw.init(): return None glfw.window_hint(glfw.SAMPLES, 4) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.create_window(width, height, "Select points", None, None) if not window: glfw.terminate() return None glfw.make_context_current(window) glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE) glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_NORMAL) glfw.set_cursor_pos_callback(window, cursor_pos_callback) glfw.set_mouse_button_callback(window, mouse_button_callback) return window # 绘制矩形 def draw_rect(x1, y1, x2, y2): glLoadIdentity() glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() gluOrtho2D(0, 800, 600, 0) glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() glDisable(GL_DEPTH_TEST) glDisable(GL_LIGHTING) glColor3f(1.0, 0.0, 0.0) glBegin(GL_LINE_LOOP) glVertex2f(x1, y1) glVertex2f(x2, y1) glVertex2f(x2, y2) glVertex2f(x1, y2) glEnd() glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW) glPopMatrix() # 鼠标按下时记录起始坐标和标志位 def mouse_button_callback(window, button, action, mods): global g_mouse_pressing, g_mouse_x1, g_mouse_y1, g_mouse_x2, g_mouse_y2 if button == glfw.MOUSE_BUTTON_LEFT and action == glfw.PRESS: g_mouse_pressing = True x, y = glfw.get_cursor_pos(window) g_mouse_x1, g_mouse_y1 = x, y g_mouse_x2, g_mouse_y2 = x, y elif button == glfw.MOUSE_BUTTON_LEFT and action == glfw.RELEASE: g_mouse_pressing = False x, y = glfw.get_cursor_pos(window) g_mouse_x2, g_mouse_y2 = x, y # 鼠标移动时更新矩形坐标并选择点云数据 def cursor_pos_callback(window, x, y): global g_mouse_x2, g_mouse_y2 if g_mouse_pressing: g_mouse_x2, g_mouse_y2 = x, y width, height = glfw.get_window_size(window) y = height - y glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45.0, float(width) / height, 0.1, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0) # 绘制矩形 draw_rect(g_mouse_x1, g_mouse_y1, g_mouse_x2, g_mouse_y2) # 选择点云数据 rect = np.array([[g_mouse_x1, y], [g_mouse_x2, y], [g_mouse_x2, g_mouse_y2], [g_mouse_x1, g_mouse_y2]]) pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(vertices) pcd.colors = o3d.utility.Vector3dVector(colors) pcd.normals = o3d.utility.Vector3dVector(normals) pcd_tree = o3d.geometry.KDTreeFlann(pcd) points = [] for i in range(4): _, idx, _ = pcd_tree.search_knn_vector_3d(rect[i], 1) points.append(idx[0]) selected_pcd = pcd.select_down_sample(points) # 绘制点云数据 glPointSize(5.0) glBegin(GL_POINTS) for i in range(len(selected_pcd.points)): glColor3f(selected_pcd.colors[i][0], selected_pcd.colors[i][1], selected_pcd.colors[i][2]) glVertex3f(selected_pcd.points[i][0], selected_pcd.points[i][1], selected_pcd.points[i][2]) glEnd() # 主函数 def main(): window = create_window(800, 600) if not window: return glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_COLOR_MATERIAL) glShadeModel(GL_SMOOTH) while not glfw.window_should_close(window): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glClearColor(0.0, 0.0, 0.0, 1.0) glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_COLOR_ARRAY) glEnableClientState(GL_NORMAL_ARRAY) glVertexPointer(3, GL_FLOAT, 0, vertices) glColorPointer(3, GL_FLOAT, 0, colors) glNormalPointer(GL_FLOAT, 0, normals) glDrawElements(GL_TRIANGLES, len(indices.flatten()), GL_UNSIGNED_INT, indices.flatten()) glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_NORMAL_ARRAY) glfw.swap_buffers(window) glfw.poll_events() glfw.terminate() if __name__ == '__main__': main() ``` 在运行该代码时,您可以使用鼠标左键点击并拖动以绘制矩形,并选择点云数据的感兴趣区域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值