Hazel游戏引擎(012)GLFW窗口事件

news2024/11/15 11:33:50

文中若有代码、术语等错误,欢迎指正

文章目录

  • 前言
  • 如何确定GLFW窗口事件的回调函数参数
  • Application接收事件回调流程
    • 原项目流程(12345)
    • 自己写的简单Demo与流程(123)

前言

  • 此节目的

    为了完成008计划窗口事件的接收glfw窗口事件以及回调部分

  • 此节要完成

    使用glfw函数可以设置(拦截)真正窗口事件的回调函数,在回调函数中转换为我们自定义的事件,再回调给Application的OnEvent,OnEvent拦截对应的事件

  • 图示部分

    图中是将Appilication的事件给Layer去处理,但本节是Application自己拦截事件并处理,修改后的图如下

如何确定GLFW窗口事件的回调函数参数

  • 引出

    glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
    

    如上代码,用lambda接收GLFW按键事件,可是为什么能确定lambda的参数

  • 需要ctrl+左键点开glfwSetKeyCallback

Application接收事件回调流程

原项目流程(12345)

对应第二张图按照1、2、3、4、5顺序

  • Application

    #include "hzpch.h"
    #include "Application.h"
    #include "Hazel/Log.h"
    #include <GLFW/glfw3.h>
    namespace Hazel {
    	#define BIND_EVENT_FN(x) std::bind(&Application::x, this, std::placeholders::_1)
    	Application::Application()
    	{
    		// 1.1Application创建窗口
    		m_Window = std::unique_ptr<Window>(Window::Create());
    		// 1.2Application设置窗口事件的回调函数
    		m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
    	}
    	// 回调glfw窗口事件的函数
    	void Application::OnEvent(Event& e)
    	{
    		// 4.用事件调度器,拦截自己层想要拦截的事件并处理
    		EventDispatcher dispatcher(e);
    		dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose));
    
    		HZ_CORE_TRACE("{0}", e);
    	}
    	void Application::Run()
    	{
    		while (m_Running)
    		{
    			glClearColor(1, 0, 1, 1);
    			glClear(GL_COLOR_BUFFER_BIT);
    			m_Window->OnUpdate();	// 更新glfw
    		}
    	}
    	// 5.执行Application的OnWinClose函数拦截处理event事件
    	bool Application::OnWindowClose(WindowCloseEvent& e)
    	{
    		m_Running = false;
    		return true;
    	}
    }
    
  • WindowsWindow.cpp

    // 2.1window创建窗口
    m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr);
    // 设置glfw当前的上下文
    glfwMakeContextCurrent(m_Window);
    /*
    	设置窗口关联的用户数据指针。这里GLFW仅做存储,不做任何的特殊处理和应用。
    	window表示操作的窗口句柄。
    	pointer表示用户数据指针。
    */
    glfwSetWindowUserPointer(m_Window, &m_Data);
    SetVSync(true);	
    // 2.2设置glfw事件回调=接收glfw窗口事件
    glfwSetWindowSizeCallback(m_Window, [](GLFWwindow* window, int width, int height){
    	// glfwGetWindowUserPointer获取void*指针可以转换为由glfwSetWindowUserPointer自定义数据类型,
        WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);
        data.Width = width;
        data.Height = height;
    
    	// 2.3将glfw窗口事件转换为自定义的事件
        WindowResizeEvent event(width, height);
    	// 3.回调Application的OnEvent函数,并将事件作为其OnEvent的参数
        data.EventCallback(event);
    });
    
  • 效果

    请添加图片描述

自己写的简单Demo与流程(123)

对应第二张图的1、2、3步(少了4、5步,可以回到009.事件系统-自定义事件细看整个事件系统的设计与流程)

#include <iostream>
#include <string>
#include <functional>
using namespace std;
using namespace std::placeholders;// 占位符空间

// 事件类定义//
class Event {							// 事件基类
public:
	virtual void Say() { cout << "Event::Say()" << endl; }
	bool m_Handled;						// 事件是否处理完
};
class WindowCloseEvent : public Event {	// 窗口关闭事件子类
public:
	virtual void Say() { cout << "WindowEvent::Say()" << endl;}
};

// 窗口类定义//
class Window {
public:
	using EventCallbackFn = std::function<void(Event&)>;	// 声明function类型void function(Event&)
	static Window* CreateWindow() {							// 模拟创建窗口
		return new Window;
	}
	void SetEventCallback(const EventCallbackFn& callback) {
		EventCallback = callback;							// 绑定Application::OnEvent
	}
	void SendEvent() {
		cout << "Window::模拟glfw窗口事件" << endl;
		// 2.将glfw窗口事件封装成自己系统的事件
		WindowCloseEvent windowe;
		// 3.回调Application的OnEvent函数,并将事件作为其OnEvent的参数
		EventCallback(windowe);
	}
	EventCallbackFn EventCallback;							// 定义function
};

// 应用层类定义//
class Application {
public:
	Window* win;											// 持有的窗口类
	void OnEvent(Event& event) {
		event.Say();
		cout << "Application::OnEvent(Event& event)" << endl;
		// 4.Application的OnEvent,将事件传递给Application的所有Layer层的OnEvent
		// ......
	}
};
int main() {
	Application app;
	// 1.1Application对象创建窗口类,窗口类初始化了glfw窗口
	app.win = Window::CreateWindow();
	// 1.2Application设置窗口事件的回调函数
	app.win->SetEventCallback(bind(&Application::OnEvent, app, _1));// bind的argument1是函数地址,arug2是哪个类,arug3是调用OnEvent的参数
	// 1.3模拟glfw窗口事件
	app.win->SendEvent();
	return 0;
}

少了Application自己拦截处理事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/635293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言之指针初阶(1)

本章重点 1. 指针是什么 2. 指针和指针类型 3. 野指针 4. 指针运算 5. 指针和数组 6. 二级指针 7. 指针数组 今天我们讲解前4个稍微简单一点的内容&#xff0c;下一篇博客讲解后三部分 首先引入话题 我们口语讲到指针&#xff0c;比如p指针&#xff0c;其实想要…

【0基础自研记录】ESP32-CAM自制个人网络监控

目的&#xff1a;实现一个小型家庭监控 一、前期准备 1.硬件准备 esp32-acm烧录板烧录线 2.软件准备 Arduion IDE CH340串口驱动 下载地址如下 Arduion IDE:https://www.arduino.cc/en/software CH340串口驱动 链接&#xff1a;https://pan.baidu.com/s/1ri8dK7wW6KFz8rOPs…

已知一个整数,如何判断这个整数是无符号的?

前言 记录6月11日&#xff0c;肯哥在群里面分享的一个问题。说实话&#xff0c;看到题目想了半天没明白。一看答案&#xff0c;才发现&#xff0c;这题真的简单。 题目 已知一个整数&#xff0c;如何判断这个整数是无符号的&#xff1f; 题解 &#xff08;1&#xff09;因为我的…

JVM相关特性

每个使用Java的开发者都知道Java字节码是在JRE中运行(JRE: Java 运行时环境)。JVM则是JRE中的核心组成部分&#xff0c;承担分析和执行Java字节码的工作&#xff0c;而Java程序员通常并不需要深入了解JVM运行情况就可以开发出大型应用和类库。尽管如此&#xff0c;如果你对JVM有…

008:vue中el-upload不显示上传的文件列表

第008个 查看专栏目录: VUE — element UI echarts&#xff0c;openlayers&#xff0c;cesium&#xff0c;leaflet&#xff0c;mapbox&#xff0c;d3&#xff0c;canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例…

废柴日记8:从入门到入狱的Python爬虫学习笔记1(入门篇)

前言&#xff1a;我错了&#xff0c;但下次也不一定(●’◡’●) 米娜桑&#xff0c;好久不见&#xff0c;不知道这段时间各位手中的西瓜刀有没有按时擦亮呢&#xff1f; 我也是在摸爬滚打将近一年之后总算是找到了一点人生的方向所以当成救命稻草现在正死死握紧不放手的啊。…

【Windows 系统笔记】使用服务器运行装载AList+本地安装RaiDrive进行网盘本地挂载

文章目录 前言准备工作一、购买一台云服务器配置服务器安装宝塔面板新建网站进入当前目录 二、安装AList三、登录四、开启域名访问五、挂载阿里云盘刷新令牌 六、使用RaiDrive挂载到本地 前言 大家肯定很好奇我为什么要写一篇这样的文章&#xff0c;因为之前一直使用本地挂载网…

SQL索引

一、索引概述 介绍&#xff1a; 索引是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0c;这样就可以…

【数据结构与算法】04 哈希表 / 散列表 (哈希函数、哈希冲突、链地址法、开放地址法、SHA256)

一种很好用&#xff0c;很高效&#xff0c;又一学就会的数据结构&#xff0c;你确定不看看&#xff1f; 一、哈希表 Hash Table1.1 核心概念1.2 哈希函数 Hash Function1.3 哈希冲突 Hash Collision1.4 哈希冲突解决1.41 方法概述1.42 链地址法 Separate Chaining1.43 开放寻址…

几种技巧让大模型(ChatGPT、文心一言)帮你提高写代码效率!

代码神器 自从大模型推出来之后&#xff0c;似乎没有什么工作是大模型不能做的。特别是在文本生成、文案写作、代码提示、代码生成、代码改错等方面都表现出不错的能力。下面我将介绍运用大模型写代码的几种方式&#xff0c;帮助程序员写出更好的代码&#xff01;&#xff08;…

华为OD机试真题 JavaScript 实现【一种字符串压缩表示的解压】【2022Q4 100分】,附详细解题思路

一、题目描述 有一种简易压缩算法&#xff1a;针对全部由小写英文字母组成的字符串&#xff0c;将其中连续超过两个相同字母的部分压缩为连续个数加该字母&#xff0c;其他部分保持原样不变。例如&#xff1a;字符串“aaabbccccd”经过压缩成为字符串“3abb4cd”。 请您编写解…

shell脚本学习记录(重定向)

Shell 输入/输出重定向 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。 输出重定向 重定向一般通过在命令间插入特定的符号来实现。特别的&#xff0c;这些符号的语法如下所示: command1 > file1 上面这个命令执行command1然后将输出的…

maven访问仓库的顺序

1.没有配置私服的情况下&#xff08;大部分情况下&#xff09; 如上图所示&#xff0c;maven是依次从本地仓库、中央仓库和第三方仓库获取依赖的&#xff0c;其实在maven中并不是以这三种类型区分的&#xff0c;在maven中只有两种仓库类型&#xff0c;本地仓库和远程仓库&#…

Systemverilog中的Driving Strength讲解

在systemverilog中&#xff0c;net用于对电路中连线进行建模&#xff0c;driving strength(驱动强度)可以让net变量值的建模更加精确。net变量拥有4态逻辑值(0,1,z,x)&#xff0c;它的driving strength有(supply,strong,pull,weak,highz)。net的值由连接到net的driver源(驱动源…

【开源工具】使用Whisper将提取视频、语音的字幕

这里写目录标题 一、语音转字幕操作步骤1、下载安装包Assets\WhisperDesktop.zip[^2]2、加载模型2.1 下载模型2.1.1 进入Hugging Face[^3]的仓库2.1.2 选择需要下载的模型2.1.3 配置模型路径 3、语音转字幕4、实时语言转录功能 二、相关简介[^1]特点开发人员指南构建说明其他注…

模拟退火(SA)算法

目录 模拟退火算法 主要代码 Mutate Sphere 模拟退火算法 主要代码 repmat 重复数组副本 B repmat(A,n) 返回一个数组&#xff0c;该数组在其行维度和列维度包含 A 的 n 个副本。A 为矩阵时&#xff0c;B 大小为 size(A)*n。 unifrnd 生成连续统一的随机数 sort 对数组进行…

抖音百科词条创建在哪里?

抖音作为中国火爆的短视频平台&#xff0c;拥有相当庞大的用户群体&#xff0c;用户在抖音上创建百科词条就可以获得非常可观的曝光和展现&#xff0c;抖音百科词条是通过哪种方式创建的呢&#xff1f;想要创建一个抖音百科怎么做&#xff1f;接下来伯乐网络传媒就来给大家讲一…

Linux之进程信号(上)

文章目录 前言一、进程信号二、查看命令kill -l与信号解释man 7 signal1.kill -l2.man 7 signal 三、信号的产生1.按键ctrl cctrl zctrl \ 2.系统调用kill——向任意进程发送信号raise——进程给自己发送任意信号abort——进程给自己指定的信号&#xff08;6号信号&#xff…

主流解压缩软件有哪些?这四款可以满足你的所有需求

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 第一款&#xff1a;bandizip&#xff08;推荐&#xff09; 第二款&#xff1a;7-zip 第三款&#xff1a;Nanazip 第四款&#xff1a…

Vue中如何进行表单自定义验证

Vue中如何进行表单自定义验证 在Vue应用中&#xff0c;表单验证是非常重要的一部分。Vue提供了一些内置的验证规则&#xff0c;比如required、min、max等。但是有时候我们需要对表单进行自定义验证&#xff0c;以满足特定的业务需求。本文将介绍如何在Vue中进行表单自定义验证…