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.mfbz.cn/a/296443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MidJourney笔记(10)-faq-fast-help-imagine-info-public-stealth

/faq 在官方 Midjourney Discord 服务器中使用可快速生成流行提示工艺频道常见问题解答的链接。 不过这个命令,我也是没有找到入口,之前还能在MidJourney的频道里使用,然后最近发现没有权限,有点奇怪。不知道系统又做了什么升级。 /fast 切换到快速模式。

七、HTML 文本格式化

一、HTML 文本格式化 加粗文本斜体文本电脑自动输出 这是 下标 和 上标 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>HTML文本格式化</title> </head><body><b>加粗文本</b><br>…

HarmonyOS应用开发学习笔记 包名、icon图标,应用名修改 UIAbility组件介绍、UIAbility启动模式、UIAbility组件基本用法

目前HarmonyOS应用主推的是Stage模型开发 一、Stage模型基本概念 项目描述UIAbility组件UIAbility组件是一种包含UI界面的应用组件&#xff0c;主要用于和用户交互。例如&#xff0c;图库类应用可以在UIAbility组件中展示图片瀑布流&#xff0c;在用户选择某个图片后&#xf…

Mysqld的关键优化参数

skip-name-resolve 现象 mysql连接很慢&#xff0c;登陆到服务器上查看服务器日志都是正常的&#xff0c;无可疑记录&#xff0c;登陆到mysql服务器上&#xff0c;查看下进程&#xff0c;发现有很多这样的连接&#xff1a; 218 | unauthenticated user | 192.168.10.6:44500 |…

Stable Diffusion架构的3D分子生成模型 GeoLDM - 测评与代码解析

之前&#xff0c;向大家介绍过3D分子生成模型 GeoLDM。 GeoLDM按照Stable Diffusion架构&#xff0c;将3D分子生成的扩散过程运行在隐空间内&#xff0c;优化了基于扩散模型的分子生成。可能是打开Drug-AIGC的关键之作。让精确控制分子生成有了希望。 详见&#xff1a;分子生成…

听GPT 讲Rust源代码--compiler(16)

File: rust/compiler/rustc_span/src/lib.rs 在Rust源代码中&#xff0c;rust/compiler/rustc_span/src/lib.rs文件定义了与Rust编译器源代码位置相关的数据结构和功能。 下面是对一些重要结构和枚举类型的详细介绍&#xff1a; SessionGlobals: 代表编译器会话&#xff08;Ses…

leetcode2975. 移除栅栏得到的正方形田地的最大面积

题目 有一个大型的 (m - 1) x (n - 1) 矩形田地&#xff0c;其两个对角分别是 (1, 1) 和 (m, n) &#xff0c;田地内部有一些水平栅栏和垂直栅栏&#xff0c;分别由数组 hFences 和 vFences 给出。 水平栅栏为坐标 (hFences[i], 1) 到 (hFences[i], n)&#xff0c;垂直栅栏为…

【大数据进阶第三阶段之Hive学习笔记】Hive查询、函数、性能优化

【大数据进阶第三阶段之Hive学习笔记】Hive安装-CSDN博客 【大数据进阶第三阶段之Hive学习笔记】Hive常用命令和属性配置-CSDN博客 【大数据进阶第三阶段之Hive学习笔记】Hive基础入门-CSDN博客 【大数据进阶第三阶段之Hive学习笔记】Hive查询、函数、性能优化-CSDN博客 ——…

2024.1.2 Spark 简介,架构,环境部署,词频统计

目录 一. Spark简介 二 . Spark 框架模块 三. 环境准备 3.1 Spark Local模式搭建 3.2 通过Anaconda安装python3环境 3.3 PySpark库安装 四 . Spark集群模式架构介绍 五. pycharm远程开发环境 六. Spark词频统计 一. Spark简介 1. Spark 和MapReduce MR:大量的磁盘反复…

LiveGBS流媒体平台GB/T28181常见问题-国标编号是什么设备编号和通道国标编号标记唯一的摄像头|视频|镜头通道

LiveGBS国标GB28181中国标编号是什么设备编号和通道国标编号标记唯一的摄像头|视频|镜头通道 1、什么是国标编号&#xff1f;2、国标设备ID和通道ID3、ID 统一编码规则4、搭建GB28181视频直播平台 1、什么是国标编号&#xff1f; 国标GB28181对接过程中&#xff0c;可能有的小…

Vue入门一(前端发展史|Vue介绍|Vue插值语法|Vue指令|style与class使用|条件渲染)

文章目录 一、前端的发展史二、Vue介绍 和 基本使用1) Vue介绍2) Vue特点3) M-V-VM思想1.MVVM介绍2.MVVM的特性3.MVVM逻辑 4) 组件化开发、单页面开发组件化开发单页面开发 5) 引入方式6) 补充解释型的语言是需要解释器的 nodejs&#xff1a;一门后端语言7) 快速使用 三、Vue之…

JavaScript异常处理详解

前言 本文将带你了解 JavaScript 中常见的错误类型&#xff0c;处理同步和异步 JavaScript代码中错误和异常的方式&#xff0c;以及错误处理最佳实践&#xff01; 1. 错误概述 JavaScript 中的错误是一个对象&#xff0c;在发生错误时会抛出该对象以停止程序。在 JavaScript…

代码随想录刷题题Day26

刷题的第二十六天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day26 任务 ● 动态规划理论基础 ● 斐波那契数 ● 爬楼梯 ● 使用最小花费爬楼梯 1 动态规划理论基础 对于动态规划问题&#x…

小白入门基础 - spring Boot 入门

1.简介 spring Boot是为了简化java的开发流程而构建的&#xff0c;即使是使用springMVC框架&#xff0c;也依然需要大量配置和依赖导入&#xff0c; 这无疑是繁琐的&#xff0c;spring Boot采用了”习惯由于配置“的原则&#xff0c;进行一键化部署&#xff0c;这样极大…

【建议收藏】一文全面解读Linux最常用的解压缩命令(tar、zip、unzip、gzip、guznip、bzip2、bunzip2)

一文全面解读Linux最常用的解压缩命令&#xff08;tar、zip、unzip、gzip、guznip、bzip2、bunzip2&#xff09;&#xff0c;建议收藏 文章目录 一文全面解读Linux最常用的解压缩命令&#xff08;tar、zip、unzip、gzip、guznip、bzip2、bunzip2&#xff09;&#xff0c;建议收…

2017年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

昨天&#xff0c;六分成长给大家了做了一套2024年AMC8比赛的全真模拟试题&#xff0c;40分钟&#xff0c;25道题&#xff0c;并且提供了答案&#xff0c;所有试题来自过去20年的真题&#xff0c;不知道你做对了多少&#xff1f;一定要让孩子抽40分钟&#xff0c;认真的做一做&a…

mnn-llm: 大语言模型端侧CPU推理优化

在大语言模型(LLM)端侧部署上&#xff0c;基于 MNN 实现的 mnn-llm 项目已经展现出业界领先的性能&#xff0c;特别是在 ARM 架构的 CPU 上。目前利用 mnn-llm 的推理能力&#xff0c;qwen-1.8b在mnn-llm的驱动下能够在移动端达到端侧实时会话的能力&#xff0c;能够在较低内存…

数字人克隆:人类科技进步的里程碑

数字人克隆&#xff0c;作为一项引起广泛争议和关注的科技创新&#xff0c;正在逐渐走向我们的生活。它是将人的意识和思想复制到数字化的实体中&#xff0c;从而使之与真正的人类无异。数字人克隆的出现不仅引发了人们对道德伦理问题的讨论&#xff0c;也给人类社会带来了巨大…

频率域图像增强之理想低通滤波器的python实现——数字图像处理

原理 理想低通滤波器&#xff08;Ideal Low-Pass Filter, ILPF&#xff09;是数字图像处理中一个重要的概念&#xff0c;尤其在频率域滤波中扮演着关键角色。 定义&#xff1a; 理想低通滤波器是一种在频率域内工作的滤波器&#xff0c;旨在通过允许低频信号通过同时阻止高频信…

mysql5.7安装-windwos免安装版本

下载地址 官网地址:https://www.mysql.com/官网下载地址:https://dev.mysql.com/downloads/mysql/阿里云镜像站下载:https://mirrors.aliyun.com/mysql/华为云镜像站地址:https://mirrors.huaweicloud.com/home华为云镜像站下载:https://mirrors.huaweicloud.com/mysql/Downlo…
最新文章