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

news2024/9/23 20:20:30


视频地址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.coloradmin.cn/o/1360427.html

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

相关文章

群晖Docker部署HomeAssistant容器结合内网穿透远程控制家中智能设备

目录 一、下载HomeAssistant镜像 二、内网穿透HomeAssistant&#xff0c;实现异地控制智能家居 三、使用固定域名访问HomeAssistant 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 Ho…

几种常见的CSS三栏布局?介绍下粘性布局(sticky)?自适应布局?左边宽度固定,右边自适应?两种以上方式实现已知或者未知宽度的垂直水平居中?

几种常见的CSS三栏布局 流体布局 效果&#xff1a; 参考代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…

【elfboard linux 开发板】9. 虚拟机扩容和内核编译

1. 虚拟机扩容 需要将虚拟机的快照全都删除&#xff0c;并且将运行的系统关机点击扩展&#xff0c;改为需要的磁盘大小安装gparted工具 sudo apt-get install gparted 如果报错&#xff0c;则按照出错内容修改&#xff0c;一般是出现下载错误&#xff0c;可以使用下列命令&…

【大数据进阶第三阶段之Hive学习笔记】Hive的数据类型与数据操作

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

集合-及其各种特征详解

集合 概念&#xff1a;是提供一种存储空间 可变 的存储模型&#xff0c;存储的数据容量可以发生改变。&#xff08;也就是集合容量不固定&#xff09; 集合关系图 绿色的代表接口&#xff0c;蓝色的代表接口的实现类 单列集合 Collection(接口) 概述&#xff1a;单列集合的…

05、Kafka ------ CMAK 各个功能的作用解释(主题和分区 详解,用命令行和图形界面创建主题和查看主题)

目录 CMAK 各个功能的作用解释&#xff08;主题&#xff09;★ 主题★ 分区★ 创建主题&#xff1a;★ 列出和查看主题 CMAK 各个功能的作用解释&#xff08;主题&#xff09; ★ 主题 Kafka 主题虽然也叫 topic&#xff0c;但它和 Pub-Sub 消息模型中 topic 主题及 AMQP 的 t…

安科瑞变电站综合自动化系统在青岛海洋科技园应用——安科瑞 顾烊宇

摘 要&#xff1a;变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计&#xff0c;利用先进的计算机技术、通信技术、信号处理技术&#xff0c;实现对全变电站的主要设备和输、配电线路的自动监视、测量、控制、保护、并与上级调度通信的综合性自动化功能。 …

深入理解Word Embeddings:Word2Vec技术与应用

目录 前言1 Word2Vec概述2 CBOW模型2.1 CBOW模型简介2.2 基于词袋&#xff08;bag of word&#xff09;的假设2.3 One-hot向量编码2.4 分类问题 3 Skip-gram模型3.1 Skip-gram模型简介3.2 目标词预测上下文3.3 词语关联性的捕捉 4 优化Word2Vec模型的方法4.1 负采样和分层softm…

谷歌浏览器启用实时字幕功能

在 Chrome 中使用“实时字幕”功能 - Google Chrome帮助 在 Chrome 中使用“实时字幕”功能 从计算机上的 Chrome 浏览器中&#xff0c;您可以使用“实时字幕”功能自动为视频、播客、游戏、直播、视频通话或其他音频媒体生成字幕。音频和字幕均在本地处理&#xff0c;并会保…

「Verilog学习笔记」编写乘法器求解算法表达式

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule calculation(input clk,input rst_n,input [3:0] a,input [3:0] b,output [8:0] c);reg [8:0] data1, data2 ; assign c data2 ; always (posed…

【Filament】自定义Blinn Phong光照模型

1 前言 光照元素主要有环境光&#xff08;ambient&#xff09;、漫反射光&#xff08;diffuse&#xff09;、镜面反射光&#xff08;specular&#xff09;&#xff0c;基础的光照模型主要有兰伯特&#xff08;Lambert&#xff09;光照模型、冯氏&#xff08;Phong&#xff09;光…

【Vue3+React18+TS4】1-1 : 课程介绍与学习指南

本书目录&#xff1a;点击进入 一、为什么做这样一门课程? 二、本门课的亮点有哪些? 2.1、轻松驾驭 2.2、体系系统 2.3、高效快捷 2.4、融合贯通 三、课程内容包括哪些? 四、项目实战 《在线考勤系统》 五、课适合哪些同学? 一、为什么做这样一门课程? 近十年内前端…

RocketMQ源码 发送消息源码分析

前言 DefaultMQProducer 是默认生产者组件&#xff0c;是生产者客户端中&#xff0c;绝大部分关于生产者和broker、nameSrv进行网络通信的功能入口。其中&#xff0c;包含发送各种形式&#xff08;同步、异步、事务、顺序&#xff09;的消息&#xff0c;针对发送消息部分的实现…

Vue页面传值:Props属性与$emit事件的应用介绍

一、vue页面传值 在Vue页面中传值有多种方式&#xff0c;简单介绍以下两种 通过props属性传递值&#xff1a;父组件在子组件上定义props属性&#xff0c;子组件通过props接收父组件传递的值。通过$emit触发事件传递值&#xff1a;子组件通过$emit方法触发一个自定义事件&#…

Meshlab界面和菜单初步认识

文章目录 界面认识菜单 界面认识 顾名思义&#xff0c;MeshLab即网格实验室&#xff0c;用于处理三维对象&#xff0c;并有着针对网格基于网格操作的各种工具&#xff0c;是一个功能强大的三维几何处理系统。因其开源&#xff0c;直接搜官网下载即可。安装过程无坑&#xff0c…

pycharm调整漂亮的颜色主题

主题样式&#xff1a; 一、设置主题为白色 二、pycharm 如何设置字体颜色 打开pycharm编辑器&#xff0c;file > settings > editor > color scheme > python > 你也可以直接用我资源中的配置好的文件

癌症早筛2023:翻越大山,仍是漫漫征途

撕开一盒试剂盒&#xff0c;拿出采样工具&#xff0c;在采集测试样本后混入试剂&#xff0c;再用试纸测试自身对某种病原体的感染情况。过去一段时间&#xff0c;这个方式帮助很多人尽早明确了新冠、流感、支原体的感染状况&#xff0c;从而加速对症治疗。 也因此&#xff0c;…

计算机进入BIOS - Win/Linux

计算机进入BIOS - Win/Linux 快捷键方法&#xff08;通用&#xff09;Win系统方法Linux系统方法 快捷键方法&#xff08;通用&#xff09; 此方法为通用方法&#xff0c;适用于任何型号的计算机&#xff0c;包括台式机和笔记本&#xff0c;也包括Win系统和Linux系统。 进入BI…

FA2016AA (MHz范围晶体单元超小型低轮廓贴片) 汽车

随着科技的不断发展&#xff0c;智能汽车逐渐成为人们出行的首选。而其中&#xff0c;频率范围在19.2 MHz ~ 54 MHz的晶体单元超小型低轮廓贴片&#xff08;FA2016AA&#xff09;为汽车打造更智能、更舒适、更安全的出行体验。FA2016AA贴片的外形尺寸为2.0 1.6 0.5 mm&#x…

【UnityShader入门精要学习笔记】(2)GPU流水线

本系列为作者学习UnityShader入门精要而作的笔记&#xff0c;内容将包括&#xff1a; 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更&#xff0c;有始无终 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 上节复习GPU流水线顶点着色…