当前位置: 首页 > news >正文

C++ OpenGL 3D Game Tutorial 2: Making OpenGL 3D Engine学习笔记

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

一、main类

        接上一篇内容,main.cpp的内容增加了一些代码,显得严谨一些:

#include<OGL3D/Game/OGame.h>
#include<iostream>int main()
{try {OGame game;game.Run();}catch (const std::exception& e){std::cout << e.what() << std::endl;return 1;}return 0;
}

二、OGame类 

       然后是Game类的添加了很多内容:

        Game.h文件:

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

        Game.cpp文件:

#include<OGL3D/Graphics/OGraphicsEngine.h>
#include<OGL3D/Window/OWindow.h>
#include<OGL3D/Game/OGame.h>
#include<Windows.h>OGame::OGame()
{m_graphicsEngine = std::make_unique<OGraphicsEngine>();m_display = std::make_unique<OWindow>();m_display->makeCurrentContext();
}OGame::~OGame()
{
}void OGame::onCreate()
{m_graphicsEngine->clear(OVec4(1,0,0,1));m_display->present(false);
}void OGame::onUpdate()
{
}void OGame::onQuit()
{
}void OGame::Run()
{onCreate();MSG msg;while (m_isRunning){msg = {};if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){if (msg.message == WM_QUIT){m_isRunning = false;continue;}else {TranslateMessage(&msg);DispatchMessage(&msg);}}onUpdate();}onQuit();
}

       和上一篇相比,在构造函数里面创建了OGraphicEngine对象,同时执行了OWindow对象m_display的方法makeCurrentContext,这个方法也是OWindow类在本次视频里面后加的。需要注意的是,这两行代码的顺序不能错:

m_graphicsEngine = std::make_unique<OGraphicsEngine>();
m_display = std::make_unique<OWindow>();

         因为OWindow构造期间需要获取的HDC里面的内容,而这个HDC内容要在OGraphicsEngine构造期间设置,所以必定要先构造OGraphicsEngine对象,顺序颠倒了肯定不行。

        同时OGame类里面还添加onCreate、onUpdate、onQuit方法,注意一下这三个方法的调用时机就好了。

三、OWindow类

Owindow.h文件

#pragma once#include<Windows.h>
class OWindow
{
public:OWindow();~OWindow();void makeCurrentContext();void present(bool vsync);
private:HWND m_handle = nullptr;HGLRC m_context = nullptr;
};

OWindow.cpp文件

#include<OGL3D/Window/OWindow.h>
#include<glad/glad.h>
#include<glad/glad_wgl.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);break;}case WM_CLOSE:{PostQuitMessage(0);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;auto classId = RegisterClassEx(&wc);assert(classId);RECT rc = { 0,0,1024,768 };AdjustWindowRect(&rc, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, false);m_handle = CreateWindowEx(NULL,MAKEINTATOM(classId),L"Parcode | OpenGL 3D Game",WS_OVERLAPPEDWINDOW,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);HDC hDC = GetDC(m_handle);int pixelFormatAttributes[] = {WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,WGL_SUPPORT_OPENGL_ARB,GL_TRUE,WGL_DOUBLE_BUFFER_ARB,GL_TRUE,WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,WGL_PIXEL_TYPE_ARB,WGL_TYPE_RGBA_ARB,WGL_COLOR_BITS_ARB,24,WGL_DEPTH_BITS_ARB,24,WGL_STENCIL_BITS_ARB,8,0};int iPixelFormat = 0;UINT numFormats = 0;wglChoosePixelFormatARB(hDC, pixelFormatAttributes, nullptr, 1, &iPixelFormat, &numFormats);assert(numFormats);PIXELFORMATDESCRIPTOR pixelFormatDesc = {};DescribePixelFormat(hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pixelFormatDesc);SetPixelFormat(hDC, iPixelFormat, &pixelFormatDesc);int openAttributes[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,4,WGL_CONTEXT_MINOR_VERSION_ARB,6,WGL_CONTEXT_PROFILE_MASK_ARB,WGL_CONTEXT_CORE_PROFILE_BIT_ARB,0};m_context = wglCreateContextAttribsARB(hDC, 0, openAttributes);assert(m_context);
}OWindow::~OWindow()
{wglDeleteContext(m_context);DestroyWindow(m_handle);
}void OWindow::makeCurrentContext()
{wglMakeCurrent(GetDC(m_handle), m_context);
}void OWindow::present(bool vsync)
{wglSwapIntervalEXT(vsync);wglSwapLayerBuffers(GetDC(m_handle), WGL_SWAP_MAIN_PLANE);
}

创建窗口

        这里需要解释一些创建窗口的问题,其实在上一篇文件里就应该解释,但是当时理解的也不到位,这里算是补充一下。 
        WNDCLASSEX创建一个名称为wc的结构体实例,这个实例相当于我们事先写一份要创建窗口的类型申请表,RegisterClass这个函数就是把wc这个申请表提交(注册)给Window系统,然后当需要创建窗口时,Window系统就会按这个申请表来创建。
        RegisterClass的形参是指向WNDCLASSEX结构体的指针,这个指针会加入到system atom table即SAT中,这样系统就可以通过查找这张表来找到用户自定义的窗口类,window预定义的窗口类指针也在SAT中。

        SAT实际上实现了一种用于查询的映射,ATOM(翻译过来叫“原子”)实际类型是short,即16整数。ATOM表(原子表)是一个系统定义的用于存放字符串和相应的标识符的表。程序把一个字符串放入ATOM表,获得一个相应的16位整数,这个整数就叫原子,可以用来访问该字符串。一个被放进原子表的字符串叫做原子名称。

        只有系统才可直接访问这张表,但在调用某些api函数时,如Registerclass,可以告知系统来存取这张表。当然,还有本地原子表和全局原子表,这些表应用程序是可以直接访问的。

        MAKEINTATOM 宏 (位于winbase.h)将指定的原子转换为对应的字符串地址,以便可以将其传递给接受原子或字符串的函数。调用CreateWindowEx就用到了这个宏。

获取绘制上下文 

        后面补充的代码是从

HDC hDC = GetDC(m_handle); 

这行代码开始,一直到

assert(m_context); 

这行代码结束,其核心的目的是获取绘制上下文,就是 m_context 。而获取上下文的代码时使用的代码是:

m_context = wglCreateContextAttribsARB(hDC, 0, openAttributes);

        总体来说对我是个晕头转向的过程,不过大概就是先要获取形参,第一个是hDC,也是唯一需要说明一下的,这个内容有点儿多,查了老半天也是很糊涂的,先能明白多少算多少。

        HDC——Handle of the Device Context,中文意思是“设备上下文句柄”,这个东西会在后面多次用到。HDC是一种包含有关某个设备(如显示器或打印机)的绘制属性信息的 Windows 数据结构。所有绘制调用都通过设备上下文对象进行,这些对象封装了用于绘制线条、形状和文本的 Windows API。

        虽然说GetDC函数很容易就获取了这个hDC,但是对其像素格式进行设置。就是下面的代码:

SetPixelFormat(hDC, iPixelFormat, &pixelFormatDesc);

        这个过程设计好几个函数,基本没看明白,估计照着写就行。

        就说一个wglChoosePixelFormatARB函数吧,它能够找到合适的像素格式。

        Windows下要通过程序设置多重采样,必须使用wglChoosePixelFormatARB这个函数。正确使用这个函数的关键,就是需要创建一个临时窗体,通过这个窗体,我们可以获取必须的基础像素格式,然后再使用wglChoosePixelFormatARB这个函数,得到可用的多重采样像素格式,最后,对渲染窗口设置这个像素格式即可。

四、OGraphicsEngine类

        新增加了OGraphicsEngine类,先贴出代码:

        OGraphicsEngine.h文件:

#pragma once
#include<OGL3D/Math/OVec4.h>class OGraphicsEngine
{
public:OGraphicsEngine();~OGraphicsEngine();
public:void clear(const OVec4& color);
};

        OGraphicsEngine.cpp文件:

#include<OGL3D/Graphics/OGraphicsEngine.h>
#include<glad/glad.h>
#include<glad/glad_wgl.h>
#include<assert.h>
#include<stdexcept>OGraphicsEngine::OGraphicsEngine()
{WNDCLASSEX wc = {};wc.cbSize = sizeof(WNDCLASSEX);wc.lpszClassName = L"OGL3DDummyWindow";wc.lpfnWndProc = DefWindowProc;wc.style = CS_OWNDC;auto classId = RegisterClassEx(&wc);assert(classId);auto dummyWindow = CreateWindowEx(NULL, MAKEINTATOM(classId), L"", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);assert(dummyWindow);HDC dummyDC = GetDC(dummyWindow);PIXELFORMATDESCRIPTOR pixelFormatDesc = {};pixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);pixelFormatDesc.nVersion = 1;pixelFormatDesc.iPixelType = PFD_TYPE_RGBA;pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;pixelFormatDesc.cColorBits = 32;pixelFormatDesc.cAlphaBits = 8;pixelFormatDesc.cDepthBits = 24;pixelFormatDesc.cStencilBits = 8;pixelFormatDesc.iLayerType = PFD_MAIN_PLANE;auto iPixelFormat = ChoosePixelFormat(dummyDC, &pixelFormatDesc);SetPixelFormat(dummyDC, iPixelFormat, &pixelFormatDesc);auto dummyContext = wglCreateContext(dummyDC);assert(dummyContext);wglMakeCurrent(dummyDC, dummyContext);if (!gladLoadWGL(dummyDC))throw std::runtime_error("OGraphic Engine Error:gladLoadWGL failed.");if (!gladLoadGL())throw std::runtime_error("OGraphic Engine Error:gladLoadGL failed.");wglMakeCurrent(dummyDC, 0);wglDeleteContext(dummyContext);ReleaseDC(dummyWindow, dummyDC);DestroyWindow(dummyWindow);
}OGraphicsEngine::~OGraphicsEngine()
{
}void OGraphicsEngine::clear(const OVec4& color)
{glClearColor(color.x,color.y,color.z,color.w);glClear(GL_COLOR_BUFFER_BIT);
}

        ​choosePixelFormat从HDC中选择最匹配的内容,返回一个索引(iPixelFormat,开头的i应该就是index)。

        SetPixelformat函数将指定设备上下文(HDC)的像素格式设置为索引(iPixelFormat)指定的格式。

        这一通操作意思就是你开始定义的PIXELFORMATDESCRIPTOR只是你自己一厢情愿的想法,设备(显示器或者打印机)有可能支持(这当然最好),也有可能不支持,一旦不支持,就给你找个最接近你要求的参数凑合用用。

        wglCreateContext(为什么是wgl开头呢?应该是来源于Wingdi.h文件的GL函数,wingdi应该就是Window Graphic Deviec Interface)函数创建一个呈现上下文,该上下文适用于在 hdc 引用的设备上绘图。 

        其返回值是HGLRC类型(the Handle of GL Rendering Context,GL渲染上下文句柄)

        wglMakeCurrent就是指示后续在hdc上的绘制工作都是基于dummyContext的。

        绕了一大圈都是为了这两句:

	if (!gladLoadWGL(dummyDC))throw std::runtime_error("OGraphic Engine Error:gladLoadWGL failed.");if (!gladLoadGL())throw std::runtime_error("OGraphic Engine Error:gladLoadGL failed.");

        先说一下,通过throw抛出异常会终止线程。

        这两句也都是对hDC状态进行设置。

五、补充

        补充两个文件,一个是OVec4.h文件,另一个是OPerequisites.h文件。

        OVec4.h文件:

#pragma once
#include<OGL3D/OPerequisites.h>class OVec4
{
public:OVec4() {}OVec4(f32 x, f32 y, f32 z, f32 w) :x(x), y(y), z(z), w(w) {}~OVec4() {}public:f32 x = 0, y = 0, z = 0, w = 0;
};

        OPerequisites.h文件:

#pragma oncetypedef float f32;

六、后记

        说实话,Window编程真的很绕,很晦涩(其实本来想说很**,但我要保持优雅的底线),也许这就是垄断的结果吧。其实以前开发苹果App的时候,感觉苹果对开发者就很不友好(对玩家用户倒是友好得很!),禁不住回想在Unity环境下用C#编程,似乎真的很美好(Long Live Unity!)。不过话说回来,开发游戏引擎的通常比使用引擎做游戏的工资更高,算是对被这种代码折磨的补偿吧 :D       

相关文章:

C++ OpenGL 3D Game Tutorial 2: Making OpenGL 3D Engine学习笔记

视频地址https://www.youtube.com/watch?vPH5kH8h82L8&listPLv8DnRaQOs5-MR-zbP1QUdq5FL0FWqVzg&index3 一、main类 接上一篇内容&#xff0c;main.cpp的内容增加了一些代码&#xff0c;显得严谨一些&#xff1a; #include<OGL3D/Game/OGame.h> #include<i…...

Redis小计(4)

目录 1.Set和Get操作 2.mset和mget 3.mset&#xff0c;mget&#xff0c;set后加参数的优点 4.incr,incrby&#xff0c;incrbyfloat 1.Set和Get操作 flushall&#xff1a;清除所有k-v键值对。&#xff08;删库跑路小技巧&#xff09; set k v[ex | px]&#xff1a;设置超时…...

【React】常用Hook函数的梳理和总结(第二篇)

1. 前言 本篇梳理和总结React中常用的Hook函数。 欢迎大家来到Hook的世界&#xff0c;真的贼好用~ 2. 常用Hook函数 Hook说明示例useState(initialState) 功能&#xff1a;为函数组件添加状态变量&#xff0c;输入可是基本数据类型或引用数据类型&#xff0c;也可以是不带参数…...

【JaveWeb教程】(15) SpringBootWeb之 响应 详细代码示例讲解

目录 SpringBootWeb请求响应2. 响应2.1 ResponseBody2.2 统一响应结果2.3 案例2.3.1 需求说明2.3.2 准备工作2.3.3 实现步骤2.3.4 代码实现2.3.5 测试2.3.6 问题分析 SpringBootWeb请求响应 2. 响应 前面我们学习过HTTL协议的交互方式&#xff1a;请求响应模式&#xff08;有…...

「 PyMuPDF专栏 」PyMuPDF为PDF文件添加注释

文章目录 一、PyMuPDF的安装与基本使用1. 安装PyMuPDF库的方法2. 导入PyMuPDF库二、新建PDF文档1. 创建一个空白的PDF文档三、添加注释1. 导入库并打开PDF文件2. 选择要添加注释的页面3. 创建并添加注释3.1. 文本注释3.1.1. 完整代码3.1.2. 注释效果图3.2. 高亮注释3.2.1. 完整…...

5 - 视图|存储过程

视图&#xff5c;存储过程 视图视图基本使用使用视图视图进阶 存储过程创建存储过程存储过程进阶存储过程参数循环结构 视图 视图是虚拟存在的表 表头下的数据在真表里 表头下的数据存储在创建视图时 在select命令访问的真表里 优点&#xff1a; 安全数据独立简单 用户无需关…...

系统学习Python——警告信息的控制模块warnings:警告过滤器-[基础知识]

分类目录&#xff1a;《系统学习Python》总目录 警告过滤器控制着警告是否被忽略、显示或转为错误&#xff08;触发异常&#xff09;。 从概念上讲&#xff0c;警告过滤器维护着一个经过排序的过滤器类别列表&#xff1b;任何具体的警告都会依次与列表中的每种过滤器进行匹配&…...

vue中高德地图使用

1、安装 npm i amap/amap-jsapi-loader --save2、封装地图组件 <template><div id"map" ref"mapcontainer"></div> </template><script> import AMapLoader from "amap/amap-jsapi-loader"; export default {befo…...

算法训练营Day33

#Java #贪心 开源学习资料 Feeling and experiences&#xff1a; 单调递增的数字&#xff1a;力扣题目链接 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&am…...

.net6解除文件上传限制。Multipart body length limit 16384 exceeded

在C#中上传文件时如果不修改默认文件的上传大小会提示Multipart body length limit 16384 exceeded这个错误提示表明你的请求中的Multipart body长度超过了16384字节的限制。这通常意味着你正在尝试发送一个太大的请求体&#xff0c;可能是因为包含了太多数据或者太大的文件。要…...

电子电器架构网络演化 —— 车载以太网TSN

电子电器架构网络演化 —— 车载以太网TSN 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…...

智能门锁触控工作原理中应用的电容式触摸芯片

智能门锁的识别技术中&#xff0c;密码几乎成为标配功能。相比机械按键的触控方式&#xff0c;电容式触控方式可以在加上一层玻璃甚至金属一体成型之后与用户进行交互&#xff0c;由于进行了物理性隔离&#xff0c;使得外壳更具完整性&#xff0c;物理上安全性更佳。电容式触控…...

Spark 中 BroadCast 导致的内存溢出(SparkFatalException)

背景 本文基于 Spark 3.1.1 open-jdk-1.8.0.352目前在排查 Spark 任务的时候&#xff0c;遇到了一个很奇怪的问题&#xff0c;在此记录一下。 现象描述 一个 Spark Application, Driver端的内存为 5GB,一直以来都是能正常调度运行&#xff0c;突然有一天&#xff0c;报…...

深度学习经典算法详细模型图

很早绘制的一些模型图&#xff0c;当时放在CSDN的草稿里&#xff0c;今天发现了&#xff0c;把它分享出来吧&#xff0c;还能更清晰的帮助理解&#xff01; 1.AlexNet(2012) 2. VGGNet(2014) 3. SqueezeNet(2016) 4. GoogleNet(2014)...

03、Kafka ------ CMAK(Kafka 图形界面管理工具) 下载、安装、启动

目录 CMAK&#xff08;Kafka 图形界面管理工具&#xff09;下载安装启动打开 cmak 图形界面 CMAK&#xff08;Kafka 图形界面管理工具&#xff09; Kafka本身并没有提供Web管理工具&#xff0c;而是推荐使用bin目录下各种工具命令来管理Kafka&#xff0c; 这些工具命令其实用起…...

复习python从入门到实践——函数function

复习python从入门到实践——函数function 函数是特别难的&#xff0c;大家一定要好好学、好好复习、反复巩固。函数没学好&#xff0c;会为后面造成很大困扰。 教科书中函数举例会稍微有点复杂。在此章复习中&#xff0c;我将整理出容易疏漏和混淆的知识点&#xff0c;并用最简…...

【Internal Server Error】pycharm解决关闭flask端口依然占用问题

Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application. 起因&#xff1a; 我们在运行flask后&#xff0c;断开服务依然保持运行&#xff0…...

torch.nn.functional.interpolate与torchvision.transforms.Resize方法对张量图像Resize应用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、非张量数据使用torch方法resize(transforms.Resize)二、张量数据使用torch方法resize(torch.nn.functional.interpolate) 前言 要使用 PyTorch 对张量进行…...

【Spring】Spring的事务管理

前言&#xff1a; package com.aqiuo.service.impl;import com.aqiuo.dao.AccountMapper; import com.aqiuo.pojo.Account; import com.aqiuo.service.AccountService; import org.springframework.jdbc.core.JdbcTemplate;import java.sql.Connection; import java.sql.SQLEx…...

配置cendos 安装docker 配置阿里云国内加速

由于我安装的cendos是镜像版。已经被配置好了。所以只需要更新相关配置信息即可。 输入 yum update自动更新所有配置 更新完成后输入 yum list docker-ce --showduplicates | sort -r 自动查询所有可用的docker版本 输入 yum install docker-ce docker-ce-cli container…...

【深度学习:Domain Adversarial Neural Networks (DANN) 】领域对抗神经网络简介

【深度学习&#xff1a;Domain Adversarial Neural Networks】领域对抗神经网络简介 前言领域对抗神经网络DANN 模型架构DANN 训练流程DANN示例 GPT示例 前言 领域适应&#xff08;DA&#xff09;指的是当不同数据集的输入分布发生变化&#xff08;这种变化通常被称为共变量变…...

STM32 ESP8266 物联网智能温室大棚 (附源码 PCB 原理图 设计文档)

资料下载: https://download.csdn.net/download/vvoennvv/88680924 一、概述 本系统以STM32F103C8T6单片机为主控芯片&#xff0c;采用相关传感器构建系统硬件电路。其中使用DHT11温湿度传感器对温度和湿度的采集&#xff0c;MQ-7一氧化碳传感器检测CO浓度&#xff0c;GP2Y101…...

【DevOps-08-1】Harbor镜像仓库介绍和安装

一、简要描述 Harbor介绍Harbor安装 下载离线安装包把下载的离线安装包上传到服务器,并且解压修改Harbor配置文件启动Harbor登录Harbor管理后台Harbor管理后台首页二、Harbor介绍 前面在部署项目时,我们主要采用Jenkins推送jar包到指定服务器,再通过脚本命令让目标服务器对当…...

第八节 vue3新特性

系列文章目录 目录 系列文章目录 前言 操作方法 总结 前言 vue3与vue2的区别及特性。 具体信息 页面不用跟标签包裹cs...

Web前端-jQuery

文章目录 jQuery1.1 jQuery 介绍1.1.1 JavaScript 库1.1.2 jQuery的概念1.1.3 jQuery的优点 1.2 jQuery 的基本使用1.2.1 jQuery 的下载1.2.2 jQuery快速入门1.2.3 jQuery入口函数1.2.4 jQuery中的顶级对象$1.2.5 jQuery 对象和 DOM 对象1.2.6. jQuery 对象和 DOM 对象转换 1.3…...

Leetcod面试经典150题刷题记录 —— 二叉搜索树篇

Leetcod面试经典150题刷题记录-系列Leetcod面试经典150题刷题记录——数组 / 字符串篇Leetcod面试经典150题刷题记录 —— 双指针篇Leetcod面试经典150题刷题记录 —— 矩阵篇Leetcod面试经典150题刷题记录 —— 滑动窗口篇Leetcod面试经典150题刷题记录 —— 哈希表篇Leetcod面…...

【大数据进阶第三阶段之ClickHouse学习笔记】ClickHouse的简介和使用

1、ClickHouse简介 ClickHouse是一种列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 开源地址…...

Linux下Redis6下载、安装和配置教程-2024年1月5日

Linux下Redis6下载、安装和配置教程-2024年1月5日 一、下载二、安装三、启动四、设置开机自启五、Redis的客户端1.Redis命令行客户端2.windows上的图形化桌面客户端 一、下载 1.Redis的官方下载&#xff1a;https://redis.io/download/ 2.网盘下载&#xff1a; 链接&#xff…...

Java后端开发——Ajax、jQuery和JSON

Java后端开发——Ajax、jQuery和JSON 概述 Ajax全称是Asynchronous Javascript and XML&#xff0c;即异步的JavaScript和 XML。Ajax是一种Web应用技术&#xff0c;该技术是在JavaScript、DOM、服务器配合下&#xff0c;实现浏览器向服务器发送异步请求。 Ajax异步请求方式不…...

ssm基于Vue的戏剧推广网站论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统戏剧推广信息管理难度大&#xff0c;容错率低&#xff0c…...

广州网站建设维护/广告推广免费发布

枚举型实质就是使用符号来表示的一组相互关联的数据. Season currentSeason,nextSeason; currentSeason Season.Spring; nextSeason currentSeason 1; Console.WriteLine("当前季节为&#xff1a;{0},{1}",int)currentSeason,currentSeason);Console.WriteLine(&q…...

广告设计的发展前景/广州seo公司官网

spreadsheet.hAspose.Cells 2.4.0版现已发布。 Aspose.Cells是一个Java组件&#xff0c;无需Microsoft Excel即可进行电子表格报告&#xff0c;具有打开加密的Excel文件&#xff0c;创建电子表格以及从JDBC ResultSet导入数据的功能。 它支持CSV&#xff0c;SpreadsheetML&…...

电商平台网站建设方案/网络营销服务公司有哪些

CentOS 6.2目录服务之LDAP&#xff08;一&#xff09; 2013-04-10 14:39:18标签&#xff1a;LDAP企业CentOS6.2IT辰逸辰逸原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律…...

初中做历史的网站/东莞互联网公司排名

应用场景-最短路径问题 看一个应用场景和问题&#xff1a; 1)战争时期&#xff0c;胜利乡有7个村庄(A, B, C, D, E, F, G) &#xff0c;现在有六个邮差&#xff0c;从G点出发&#xff0c;需要分别把邮件分别送到 A, B, C , D, E, F 六个村庄2)各个村庄的距离用边线表示(权) &am…...

做内贸只要有什么网络推广网站/网站运营seo实训总结

涉及到的api方法 drawImage() 方法在画布上绘制图像、画布或视频。 drawImage() 方法也能够绘制图像的某些部分&#xff0c;以及/或者增加或减少图像的尺寸。 在画布上定位图像&#xff1a; JavaScript 语法&#xff1a;context.drawImage(img,x,y);在画布上定位图像&#xff0…...

物流网站建设费用/关键词优化的作用

【目标检测-网络测试1】RFBNet代码复现及问题解决参考文章&#xff1a; &#xff08;1&#xff09;【目标检测-网络测试1】RFBNet代码复现及问题解决 &#xff08;2&#xff09;https://www.cnblogs.com/fanzhongjie/p/11504691.html &#xff08;3&#xff09;https://www.…...