C++ OpenGL 3D GameTutorial 1:Making the window with win32 API学习笔记


视频地址icon-default.png?t=N7T8https://www.youtube.com/watch?v=jHcz22MDPeE&list=PLv8DnRaQOs5-MR-zbP1QUdq5FL0FWqVzg

 一、入口函数

         首先看入口函数main代码:

#include<OGL3D/Game/OGame.h>int main()
{OGame game;game.Run();return 0;
}

        这里交代个关于C++语法的问题,这里OGame game;这行语句实际上是已经构造了一个OGame对象,并且名字叫game,如果想要想C#里面一样使用new关键字的写法的话,应该是这样的:

OGame* game = new OGame();
game->Run();

        是不是应该可以这样理解,new关键字实际上是新开辟了一个内存的意思,返回的是这块内存的指针,所以实际上是把值赋给了OGame*这个指向OGame类的指针。

        C#里面的new应该也是一个意思,但是写法上让开发者以为是赋给了一个对象,而不是一个指针,嗯,应该是这样吧。

 二、OGame类

        先贴代码:

        OGame.h

#pragma once
#include<memory>class OWindow;
class OGame
{
public:OGame();~OGame();void Run();void Quit();
protected:bool m_isRunning = true;std::unique_ptr<OWindow> m_display;
};

         OGame.cpp

#include<OGL3D/Game/OGame.h>
#include<OGL3D/Window/OWindow.h>
#include<Windows.h>OGame::OGame()
{m_display = std::unique_ptr<OWindow>(new OWindow());
}OGame::~OGame()
{
}void OGame::Run()
{MSG msg;while (m_isRunning && !m_display->isClosed()){if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}Sleep(1);}
}void OGame::Quit()
{m_isRunning = false;
}

        先看一下std::unique_ptr智能指针:

std::unique_ptr<OWindow> m_display;

        这行代码定义了一个名称为m_display的指向OWindow类型对象的智能指针,需要

#include<memory>;

        据说这东西能智能释放内存,呵呵,先这么理解吧,将来看效果。

        与PeekMessage类似的还有一个GetMessage函数,两者的不同在于在没有消息返回的情况下,PeekMessage会返回一个空值,而GetMessage会让程序休眠。还有就是GetMessage在从消息队列中取出消息后,一定会删除消息,但是PeekMessage可以通过最后参数来决定是否移除消息。GetMessage理解为“拿走”了消息,PeekMessage理解为“偷看”了消息,不一定“拿走”。我们这里把PeekMessage的最后一个参数设置为PM_REMOVE,就是“拿走”了的情形。

        TranslateMessage函数是用来把键盘消息转换为字符消息,并将转换后的新消息重新投递到调用线程的消息队列中。

        比如说当我们敲击键盘上的某个字符键时,系统将产生WM_KEYDOWN和WM_KEYUP消息。这两个消息的附加参数( wParam和 lParam)包含的是 虚拟键代码和扫描码等信息,而 我们在程序中往往需要得到某个字符的ASCII码,TranslateMessage这个函数就可以将WM_KEYDOWN和WM_ KEYUP消息的组合转换为一条WM_CHAR消息(该消息的wParam附加参数包含了字符的ASCII码),并将转换后的新消息投递到调用线程的消息队列中。注意,TranslateMessage函数并不会修改原有的消息。

        DispatchMessage这网上说得比较复杂,看着头大,我的理解是这个函数把消息发送给了窗口对象中lpfnWndProc属性所对应的函数,具体得分发机制慢慢研究,不过咱这程序里面就一个窗口,想发错了都没机会,没啥好说的。

三、OWindow类

        先贴代码:

        OWindow.h

#include<Windows.h>
class OWindow
{
public:OWindow();~OWindow();void OnDestroy();bool isClosed();
private:HWND m_handle = nullptr;
};

        OWindow.cpp

#include<OGL3D/Window/OWindow.h>
#include <Windows.h>
#include<assert.h>LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch (msg){case WM_DESTROY:{OWindow* window = (OWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);window->OnDestroy();break;}default:return DefWindowProc(hwnd, msg, wParam, lParam);}return NULL;
}OWindow::OWindow()
{WNDCLASSEX wc = {};wc.cbSize = sizeof(WNDCLASSEX);wc.lpszClassName = L"OGL3DWindow";wc.lpfnWndProc = WndProc;assert(RegisterClassEx(&wc));RECT rc = { 0,0,1024,768 };AdjustWindowRect(&rc, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, false);m_handle = CreateWindowEx(NULL, L"OGL3DWindow", L"Parcode | OpenGL 3D Game", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, NULL, NULL);assert(m_handle);SetWindowLongPtr(m_handle, GWLP_USERDATA, (LONG_PTR)this);ShowWindow(m_handle, SW_SHOW);UpdateWindow(m_handle);
}OWindow::~OWindow()
{DestroyWindow(m_handle);
}void OWindow::OnDestroy()
{m_handle = nullptr;
}bool OWindow::isClosed()
{return !m_handle;
}

        字符串前面为什么加L?表示奖ANSI字符串转换成unicode字符串,这样每个字符占用两个字节。

        RegisterClassEx这个似乎就是用来注册窗口用的,大概就是将窗口的指针添加到一个列表里面,以方便遍历查找吧。RegisterClassEx依据编译环境来决定替换为RegisterClassExA或者RegisterClassExW。如果使用RegisterClassExA来注册窗口类,应用程序通知系统被注册类的窗回的消息使用ANSI字符集的文本和字符参数;如果使用RegisterClassExW来注册窗口类,应用程序需要系统以Unicode来传递消息的文本参数。也就是是在当前的环境下RegisterClassEx应该是等同于RegisterClassExW,这样要求消息字符串必须是unicode字符串,这就看出来前面说的消息字符串前面加字母L的必要性。

        SetWindowLongPtr函数用来设置一个窗口的扩展风格或者额外数据。这个函数兼容32位和64位版本的Windows系统。这里是把指向OWindow对象的指针转化为LONG_PRT类型并保存在窗口数据偏移了GWLP_USERDATA这个位置。好吧,不是很理解,总之指向OWindow对象的指针被保存了,将来需要的时候能取出来,并以此来访问到OWindow对象就是了。我们可以从WinProc方法里面看到对应于SetWindowLongPtr函数的GetWindowLongPtr函数是如何取值并调用方法的:

OWindow* window = (OWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
window->OnDestroy();

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

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

相关文章

释放创造力:可视化页面渲染引擎在低代码开发平台的应用

本文由葡萄城技术团队发布。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 什么是页面渲染引擎? 页面渲染引擎是低代码开发平台的核心组件之一&#xff0c;它负责将开发者设计的页面布局和用户…

计算机网络学习笔记(5)——运输层

本文继续整理计算机网络体系架构知识内容。今日主讲——运输层。 网络层只把分组发送到目的主机&#xff0c;但是真正通信的并不是主机而是主机中的进程。 运输层提供了应用进程间的逻辑通信。运输层向高层用户屏蔽了下面网络层的核心细节&#xff0c;使应用程序看 见的好像在两…

python+selenium爬虫笔记

本文只是做例子&#xff0c;具体网站路径麻烦你们换下&#xff0c;还有xpath路径也换下 一、安装所需要的组件&#xff08;此处采用谷歌&#xff09; 1、安装驱动 查看你的浏览器版本&#xff0c;去安装对应的版本 下载驱动 下载驱动路径 之前版本的 输入这个路径下载下来解压…

TikTok革新游戏规则:解读短视频对社交媒体的影响

在社交媒体的巨浪中&#xff0c;TikTok以其独特的短视频形式和强大的创意社区&#xff0c;重新定义了游戏规则。这个以15秒视频为核心的平台&#xff0c;不仅让用户获得了表达自我的新方式&#xff0c;更深刻地影响了社交媒体的演进。本文将深入解读TikTok对社交媒体的影响&…

支持下载和阅读的漫画管理工具Teemii

什么是 Teemii &#xff1f; Teemii 是一款专为狂热漫画读者设计的精简 Web 应用程序。它为阅读和管理漫画集提供了一个简单而高效的平台。主要功能包括跨平台访问、浏览器内阅读、强大的元数据聚合器以及馆藏自动更新。Teemii 是专为那些寻求更加个性化和自主的方法来管理漫画…

[Kubernetes]4. 借助腾讯云TKE快速创建Pod、Deployment、Service部署k8s项目

前面讲解了通过命令行方式来部署k8s项目,下面来讲讲通过腾讯云TKE来快速创建Pod、Deployment、Service部署k8s项目,云平台搭建Kubernetes可参考[Kubernetes]1.Kubernetes(K8S)介绍,基于腾讯云的K8S环境搭建集群以及裸机搭建K8S集群 一.通过腾讯云TKE创建集群 1.创建集群 参考上…

Kibana 自定义索引连接器告警

一、 创建索引 PUT ipu-cbs-warning-info{"settings" : {"number_of_shards" : 1},"mappings" : {"properties" : {"timestamp": {"type": "date"},"rule_id" : { "type" : "…

经纬度的作用

当我们在手机上使用导航软件或者在网上查找地址时&#xff0c;经常会发现一个选项&#xff0c;就是显示当前位置的经纬度。那么&#xff0c;什么是经纬度&#xff0c;它有什么作用呢&#xff1f; 经纬度是用来确定地球上任何一个点位置的坐标系统。它由两个数值组成&#xff0…

【完整流程】实现STM32+ESP8266+MQTT+阿里云+APP——【第二节-编写STM32程序初步实现ESP8266上云发布订阅消息】

&#x1f31f;博主领域&#xff1a;嵌入式领域&人工智能&软件开发 前言&#xff1a;本节实现&#xff0c;硬件连接STM32与ESP8266&#xff0c;编写STM32程序通过at命令方式实现STM32ESP8266与阿里云物联网平台发布订阅消息&#xff0c;本节最终实现初步的发布订阅消息…

2024年AMC8竞赛真题模拟比赛做一做(25题40分钟,含答案)

这两天陆续有家长朋友问我是否有2024年AMC8比赛的模拟题&#xff0c;有一些家长是想通过做模拟题来检查孩子的学习和备考情况&#xff0c;另外一些家长式准备“谋定而后动”&#xff0c;想让孩子先做一做&#xff0c;看看难不难&#xff0c;如果还可以再报名2024年的AMC8竞赛。…

芯课堂 | LVG免费开源GUI图形库

概述 本文介绍目前LVGL的应用小知识&#xff0c;希望对采用MCU设计UI界面的用户有所启发&#xff0c;开发出界面更友好的消费品或者工业产品&#xff0c;造福大众。 01.LVGL系统架构 LVGL系统框架 应用程序创建GUI并处理特定任务的应用程序。 LVGL本身是一个图形库。我们的…

Python Selenium如何下载网页中的图片到本地?(Base64编码的图片下载)

前言&#xff1a; 在网页上&#xff0c;图片有时会以Base64编码的形式嵌入在HTML中&#xff0c;而不是作为单独的文件提供。这种方式的优点是可以减少HTTP请求的数量&#xff0c;因为图片数据直接包含在HTML中&#xff0c;不需要额外的请求来获取图片文件。这对于小图片…

【TC3xx芯片】TC3xx芯片的GTM模块详解

目录 前言 正文 1.GTM模块功能概述 1.1 GTM具体功能 1.2 GTM架构 2. GTM模块输入时钟 2.1.fGTM的值怎么计算 3. CMU 3.1 CMU功能 3.2 CMU时钟的计算 3..2.1 CLS0_CLK怎么计算 3.2.1 GTM Global Clock时钟计算 3.2.2 分频时钟的计算 4. CCM 4.1 CCM功能 4.2 CCM…

SpringMVC-视图

SpringMVC中的视图实现了View接口&#xff0c;作用是渲染数据&#xff0c;将Model中的数据展示给用户。render是渲染方法&#xff0c;可以看到渲染的视图是一个View类型的对象。 SpringMVC视图的种类有很多&#xff0c;默认有转发视图和重定向视图。 如果配置了Thymeleaf视图解…

使用Docker方式安装Artifactory

1、安装前环境准备 首先要关闭防火墙&#xff0c;关闭Selinux&#xff0c;准备好安装好的docker。以下安装版本&#xff1a;7.19.10 ##关闭防火墙&#xff0c;并设置开机自关闭 systemctl stop firewalld.service systemctl disable firewalld.service ##查看防火墙状态 sy…

SpringCloud Alibaba之Nacos配置中心配置详解

目录 Nacos配置中心数据模型Nacos配置文件加载Nacos配置 Nacos配置中心数据模型 Nacos 数据模型 Key 由三元组唯一确定&#xff0c;三元组分别是Namespace、Group、DataId&#xff0c;Namespace默认是公共命名空间&#xff08;public&#xff09;&#xff0c;分组默认是 DEFAUL…

『年度总结』逐梦编程之始:我的2023学习回顾与展望

目录 前言 我与Python 我与C语言 第一篇正式博客&#xff1a; 第二篇正式博客&#xff08;扫雷&#xff09;&#xff1a; 指针学习笔记: C语言学习笔记&#xff1a; 我与数据结构&#xff1a; yuan 这篇博客&#xff0c;我将回顾2023年编程之旅的起点&#xff0c;同时展…

Flowable中6种部署方式

1. addClasspathResource src/main/resources/processes/LeaveProcess.bpmn20.xml Deployment deploy repositoryService.createDeployment().name("请假审批").addClasspathResource("processes/LeaveProcess.bpmn20.xml").deploy();2. addInputStream…

pandas.DataFrame() 数据自动写入Excel

DataFrame 表格数据格式 &#xff1b; to_excel 写入Excel数据&#xff1b; read_excel 阅读 Excel数据函数 import pandas as pd#df2 pd.DataFrame({neme: [zhangsan, lisi, 3]}) df1 pd.DataFrame({One: [1, 2, 3],name: [zhangsan, lisi, 3]})#One是列明&#xff0c;123是…