跟着cherno手搓游戏引擎【20】混合(blend)

抽象:

Renderer.h:

#pragma once
#include"RenderCommand.h"
#include "OrthographicCamera.h"
#include"Shader.h"
namespace YOTO {class Renderer {public:static void Init();static void BeginScene(OrthographicCamera& camera);static void EndScene();static void Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray,const glm::mat4&transform = glm::mat4(1.0f));inline static RendererAPI::API GetAPI() {return RendererAPI::GetAPI();}private:struct SceneData {glm::mat4 ViewProjectionMatrix;};static SceneData* m_SceneData;};}

Renderer.cpp:

#include"ytpch.h"
#include"Renderer.h"
#include <Platform/OpenGL/OpenGLShader.h>
namespace YOTO {Renderer::SceneData* Renderer::m_SceneData = new	Renderer::SceneData;void Renderer::Init(){RenderCommand::Init();}void Renderer::BeginScene(OrthographicCamera& camera){m_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix();}void Renderer::EndScene(){}void Renderer::Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray, const glm::mat4& transform){shader->Bind();std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_ViewProjection", m_SceneData->ViewProjectionMatrix);std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_Transform", transform);/*	mi.Bind();*/vertexArray->Bind();RenderCommand::DrawIndexed(vertexArray);}
}

 RenderCommand.h:

#pragma once
#include"RendererAPI.h"
namespace YOTO {class RenderCommand{public:inline static void Init() {s_RendererAPI->Init();}inline static void SetClearColor(const glm::vec4& color) {s_RendererAPI->SetClearColor(color);}inline static void Clear() {s_RendererAPI->Clear();}inline static void DrawIndexed(const Ref<VertexArray>& vertexArray) {s_RendererAPI->DrawIndexed(vertexArray);}private:static RendererAPI* s_RendererAPI;};}

 RendererAPI.h:

#pragma once
#include<glm/glm.hpp>
#include "VertexArray.h"
namespace YOTO {class RendererAPI{public:enum class API {None = 0,OpenGL = 1};public:virtual void Init() = 0;virtual void SetClearColor(const glm::vec4& color)=0;virtual void Clear() = 0;virtual void DrawIndexed(const Ref<VertexArray>& vertexArray)=0;inline static API GetAPI() { return s_API; }private:static API s_API;};
}

实现:

OpenGLRendererAPI.h

#pragma once
#include"YOTO/Renderer/RendererAPI.h"
namespace YOTO {class OpenGLRendererAPI:public RendererAPI{public:virtual void Init()override;virtual void SetClearColor(const glm::vec4& color)override;virtual void Clear()override;virtual void DrawIndexed(const Ref<VertexArray>& vertexArray) override;};
}

 OpenGLRendererAPI.h

#include "ytpch.h"
#include "OpenGLTexture.h"
#include<glad/glad.h>
#include"stb_image.h"
namespace YOTO {OpenGLTexture2D::OpenGLTexture2D(const std::string path):m_Path(path){int width, height, channels;stbi_set_flip_vertically_on_load(1);//翻转stbi_uc*data=stbi_load(path.c_str(),&width,&height,&channels,0);YT_CORE_ASSERT(data, "图片加载错误");m_Width = width;m_Height = height;GLenum internalFormat = 0,dataFormat=0;if (channels == 4) {internalFormat = GL_RGBA8;dataFormat = GL_RGBA;}else if (channels==3) {internalFormat = GL_RGB8;dataFormat = GL_RGB;}YT_CORE_ASSERT(internalFormat& dataFormat,"OpenGLTexture2D:不支持的颜色格式")//创建纹理glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID);///告诉OpenGLm_RendererID的纹理存储的是rbg8位,宽高的缓冲区glTextureStorage2D(m_RendererID, 1, internalFormat,m_Width,m_Height);//配置参数:纹理放大时用周围颜色的平均值过滤glTextureParameteri(m_RendererID,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, dataFormat,GL_UNSIGNED_BYTE,data);stbi_image_free(data);}OpenGLTexture2D::~OpenGLTexture2D(){glDeleteTextures(1,&m_RendererID);}void OpenGLTexture2D::Bind(uint32_t slot) const{glBindTextureUnit(slot, m_RendererID);}
}

  OpenGLRendererAPI.cpp

#include "ytpch.h"
#include "OpenGLRendererAPI.h"
#include <glad/glad.h>
namespace YOTO {void OpenGLRendererAPI::Init(){//启用混合glEnable(GL_BLEND);//设置混合函数glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}void OpenGLRendererAPI::SetClearColor(const glm::vec4& color){glClearColor(color.r, color.g, color.b, color.a);}void OpenGLRendererAPI::Clear(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);}void OpenGLRendererAPI::DrawIndexed(const Ref<VertexArray>& vertexArray){glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);}
}

调用:

Application.cpp:

#include"ytpch.h"
#include "Application.h"#include"Log.h"
#include "YOTO/Renderer/Renderer.h"
#include"Input.h"
#include <GLFW/glfw3.h>namespace YOTO {
#define BIND_EVENT_FN(x) std::bind(&x, this, std::placeholders::_1)Application* Application::s_Instance = nullptr;Application::Application(){YT_CORE_ASSERT(!s_Instance, "Application需要为空!")s_Instance = this;//智能指针m_Window = std::unique_ptr<Window>(Window::Creat());//设置回调函数m_Window->SetEventCallback(BIND_EVENT_FN(Application::OnEvent));m_Window->SetVSync(false);Renderer::Init();//new一个Layer,放在最后层进行渲染m_ImGuiLayer = new ImGuiLayer();PushOverlay(m_ImGuiLayer);	}Application::~Application() {}/// <summary>/// 所有的Window事件都会在这触发,作为参数e/// </summary>/// <param name="e"></param>void Application::OnEvent(Event& e) {//根据事件类型绑定对应事件EventDispatcher dispatcher(e);dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(Application::OnWindowClosed));//输出事件信息YT_CORE_INFO("Application:{0}", e);for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {(*--it)->OnEvent(e);if (e.m_Handled)break;}}bool Application::OnWindowClosed(WindowCloseEvent& e) {m_Running = false;return true;}void Application::Run() {WindowResizeEvent e(1280, 720);if (e.IsInCategory(EventCategoryApplication)) {YT_CORE_TRACE(e);}if (e.IsInCategory(EventCategoryInput)) {YT_CORE_ERROR(e);}while (m_Running){float time = (float)glfwGetTime();//window平台Timestep timestep = time - m_LastFrameTime;m_LastFrameTime = time;for (Layer* layer : m_LayerStack) {layer->OnUpdate(timestep);}//将ImGui的刷新放到APP中,与Update分开m_ImGuiLayer->Begin();for (Layer* layer : m_LayerStack) {layer->OnImGuiRender();}m_ImGuiLayer->End();m_Window->OnUpdate();}}void Application::PushLayer(Layer* layer) {m_LayerStack.PushLayer(layer);layer->OnAttach();}void Application::PushOverlay(Layer* layer) {m_LayerStack.PushOverlay(layer);layer->OnAttach();}
}

SandboxApp.cpp:

#include<YOTO.h>
#include "imgui/imgui.h"
#include<stdio.h>
#include <glm/gtc/matrix_transform.hpp>
#include <Platform/OpenGL/OpenGLShader.h>
#include <glm/gtc/type_ptr.hpp>
class ExampleLayer:public YOTO::Layer
{
public:ExampleLayer():Layer("Example"),  m_Camera(-2.0f, 2.0f, -2.0f, 2.0f), m_CameraPosition(0){uint32_t indices[3] = { 0,1,2 };float vertices[3 * 7] = {-0.5f,-0.5f,0.0f, 0.8f,0.2f,0.8f,1.0f,0.5f,-0.5f,0.0f,  0.2f,0.3f,0.8f,1.0f,0.0f,0.5f,0.0f,   0.8f,0.8f,0.2f,1.0f,};m_VertexArray.reset(YOTO::VertexArray::Create());YOTO::Ref<YOTO::VertexBuffer> m_VertexBuffer;m_VertexBuffer.reset(YOTO::VertexBuffer::Create(vertices, sizeof(vertices)));{YOTO::BufferLayout setlayout = {{YOTO::ShaderDataType::Float3,"a_Position"},{YOTO::ShaderDataType::Float4,"a_Color"}};m_VertexBuffer->SetLayout(setlayout);}m_VertexArray->AddVertexBuffer(m_VertexBuffer);YOTO::Ref<YOTO::IndexBuffer>m_IndexBuffer;m_IndexBuffer.reset(YOTO::IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t)));m_VertexArray->AddIndexBuffer(m_IndexBuffer);std::string vertexSource = R"(#version 330 corelayout(location = 0) in vec3 a_Position;layout(location = 1) in vec4 a_Color;uniform mat4 u_ViewProjection;uniform mat4 u_Transform;out vec3 v_Position;out vec4 v_Color;void main(){v_Position=a_Position;v_Color=a_Color;gl_Position =u_ViewProjection *u_Transform* vec4( a_Position,1.0);})";//绘制颜色std::string fragmentSource = R"(#version 330 corelayout(location = 0) out vec4 color;in vec3 v_Position;in vec4 v_Color;void main(){color=vec4(v_Color);})";m_Shader.reset(YOTO::Shader::Create(vertexSource, fragmentSource));///测试/m_SquareVA.reset(YOTO::VertexArray::Create());float squareVertices[5 * 4] = {-0.5f,-0.5f,0.0f, 0.0f,0.0f,0.5f,-0.5f,0.0f,  1.0f,0.0f,0.5f,0.5f,0.0f,   1.0f,1.0f,-0.5f,0.5f,0.0f,  0.0f,1.0f,};YOTO::Ref<YOTO::VertexBuffer> squareVB;squareVB.reset(YOTO::VertexBuffer::Create(squareVertices, sizeof(squareVertices)));squareVB->SetLayout({{YOTO::ShaderDataType::Float3,"a_Position"},{YOTO::ShaderDataType::Float2,"a_TexCoord"}});m_SquareVA->AddVertexBuffer(squareVB);uint32_t squareIndices[6] = { 0,1,2,2,3,0 };YOTO::Ref<YOTO::IndexBuffer> squareIB;squareIB.reset((YOTO::IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t))));m_SquareVA->AddIndexBuffer(squareIB);//测试:std::string BlueShaderVertexSource = R"(#version 330 corelayout(location = 0) in vec3 a_Position;uniform mat4 u_ViewProjection;uniform mat4 u_Transform;out vec3 v_Position;void main(){v_Position=a_Position;gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);})";//绘制颜色std::string BlueShaderFragmentSource = R"(#version 330 corelayout(location = 0) out vec4 color;in vec3 v_Position;uniform vec3 u_Color;void main(){color=vec4(u_Color,1.0);})";m_BlueShader.reset(YOTO::Shader::Create(BlueShaderVertexSource, BlueShaderFragmentSource));std::string textureVertexSource = R"(#version 330 corelayout(location = 0) in vec3 a_Position;layout(location = 1) in vec2 a_TexCoord;uniform mat4 u_ViewProjection;uniform mat4 u_Transform;out vec2 v_TexCoord;out vec3 v_Position;void main(){v_TexCoord=a_TexCoord;v_Position=a_Position;gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);})";//绘制颜色std::string textureFragmentSource = R"(#version 330 corelayout(location = 0) out vec4 color;in vec3 v_Position;in vec2 v_TexCoord;uniform sampler2D u_Texture ;void main(){color = texture(u_Texture, v_TexCoord);	//	color = vec4(v_TexCoord, 0.0f, 1.0f);	})";m_TextureShader.reset(YOTO::Shader::Create(textureVertexSource, textureFragmentSource));m_Texture=YOTO::Texture2D::Create("assets/textures/Checkerboard.png");m_ChernoLogo= YOTO::Texture2D::Create("assets/textures/ChernoLogo.png");std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_TextureShader)->Bind();std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_TextureShader)->UploadUniformInt("u_Texture", 0);}void OnImGuiRender() override {ImGui::Begin("设置");ImGui::ColorEdit3("正方形颜色", glm::value_ptr(m_SquareColor));ImGui::End();}void OnUpdate(YOTO::Timestep ts)override {//YT_CLIENT_TRACE("delta time {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());if (YOTO::Input::IsKeyPressed(YT_KEY_LEFT)) {m_CameraPosition.x -= m_CameraMoveSpeed* ts;}else if (YOTO::Input::IsKeyPressed(YT_KEY_RIGHT)) {m_CameraPosition.x += m_CameraMoveSpeed * ts;}if (YOTO::Input::IsKeyPressed(YT_KEY_DOWN)) {m_CameraPosition.y -= m_CameraMoveSpeed * ts;}else if (YOTO::Input::IsKeyPressed(YT_KEY_UP)) {m_CameraPosition.y += m_CameraMoveSpeed * ts;}if (YOTO::Input::IsKeyPressed(YT_KEY_A)) {m_CameraRotation += m_CameraRotationSpeed * ts;}else if (YOTO::Input::IsKeyPressed(YT_KEY_D)) {m_CameraRotation -= m_CameraRotationSpeed * ts;}YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });YOTO::RenderCommand::Clear();m_Camera.SetPosition(m_CameraPosition);m_Camera.SetRotation(m_CameraRotation);YOTO::Renderer::BeginScene(m_Camera);{static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f)); glm::vec4  redColor(0.8f, 0.3f, 0.3f, 1.0f);glm::vec4  blueColor(0.2f, 0.3f, 0.8f, 1.0f);/*		YOTO::MaterialRef material = new YOTO::MaterialRef(m_FlatColorShader);YOTO::MaterialInstaceRef mi = new YOTO::MaterialInstaceRef(material);mi.setValue("u_Color",redColor);mi.setTexture("u_AlbedoMap", texture);squreMesh->SetMaterial(mi);*/std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->Bind();std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->UploadUniformFloat3("u_Color",m_SquareColor);for (int y = 0; y < 20; y++) {for (int x = 0; x <20; x++){glm::vec3 pos(x * 0.105f,y* 0.105f, 0.0);glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * scale;/*if (x % 2 == 0) {m_BlueShader->UploadUniformFloat4("u_Color", redColor);}else {m_BlueShader->UploadUniformFloat4("u_Color", blueColor);}*/YOTO::Renderer::Submit(m_BlueShader, m_SquareVA, transform);}}m_Texture->Bind();YOTO::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));m_ChernoLogo->Bind();YOTO::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));//YOTO::Renderer::Submit(m_Shader, m_VertexArray);YOTO::Renderer::EndScene();}}void OnEvent(YOTO::Event& event)override {/*if (event.GetEventType() == YOTO::EventType::KeyPressed) {YOTO:: KeyPressedEvent& e = (YOTO::KeyPressedEvent&)event;YT_CLIENT_TRACE("ExampleLayer:{0}",(char)e.GetKeyCode());if (e.GetKeyCode()==YT_KEY_TAB) {YT_CLIENT_INFO("ExampleLayerOnEvent:TAB按下了");}}*///YT_CLIENT_TRACE("SandBoxApp:测试event{0}", event);}private:YOTO::Ref<YOTO::Shader> m_Shader;YOTO::Ref<YOTO::VertexArray> m_VertexArray;YOTO::Ref<YOTO::Shader> m_BlueShader,m_TextureShader;YOTO::Ref<YOTO::VertexArray> m_SquareVA;YOTO::Ref<YOTO::Texture2D> m_Texture,m_ChernoLogo;YOTO::OrthographicCamera m_Camera;glm::vec3 m_CameraPosition;float m_CameraMoveSpeed = 5.0f;float m_CameraRotation = 0;float m_CameraRotationSpeed = 180.0f;glm::vec3 m_SquareColor = { 0.2f,0.3f,0.7f };};class Sandbox:public YOTO::Application
{
public:Sandbox(){PushLayer(new ExampleLayer());//PushLayer(new YOTO::ImGuiLayer());}~Sandbox() {}private:};YOTO::Application* YOTO::CreateApplication() {printf("helloworld");return new Sandbox();
}

加了个init涉及了好几个类,小改动,为了方便观察,我把整个类都复制下来了。

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

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

相关文章

天拓四方:边缘计算网关功能、特点与应用举例

传统的数据处理方式面临网络延迟、带宽限制和安全风险等问题。为了解决这些问题&#xff0c;边缘计算技术应运而生&#xff0c;而边缘计算网关作为其核心组件&#xff0c;正发挥着越来越重要的作用。边缘计算网关位于数据源和云数据中心之间。它具备数据采集、协议转换、数据处…

Oracle 执行计划(Explain Plan)

执行计划&#xff1a;一条查询语句在 ORACLE 中的执行过程或访问路径的描述。即就是对一个查询任务&#xff0c;做出一份怎样去完成任务的详细方案。 如果要分析某条 SQL 的性能问题&#xff0c;通常我们要先看 SQL 的执行计划&#xff0c;看看 SQL 的每一步执行是否存在问题。…

视觉SLAM十四讲学习笔记(一)初识SLAM

目录 前言 一、传感器 1 传感器分类 2 相机 二、经典视觉 SLAM 框架 1 视觉里程计 2 后端优化 3 回环检测 4 建图 5 SLAM系统 三、SLAM 问题的数学表述 四、Ubuntu20.04配置SLAM十四讲 前言 SLAM: Simultaneous Localization and Mapping 同时定位与地图构建&#…

交友系统---让陌生人变成熟悉人的过程。APP小程序H5三端源码交付,支持二开。

随着社交网络的发展和普及&#xff0c;人们之间的社交模式正在发生着深刻的变革。传统的线下交友方式已经逐渐被线上交友取而代之。而同城交友正是这一趋势的产物&#xff0c;它利用移动互联网的便利性&#xff0c;将同城内的人们连接在一起&#xff0c;打破了时空的限制&#…

机器视觉系统设计:视觉系统中的成像基准

开发视觉系统的一个重要活动是验证其部署是否符合工程规范。一个成功的视觉应用程序的两个特点是它无需工程师干涉情况下正常工作了多长时间&#xff0c;以及它的维护和复制部署是多么简易。实现所有如上所述目标的一个关键步骤是确定视觉系统的基准。 在这里使用的上下文中&a…

移动云ONAIR媒体云全解读!媒体内容数字化融合一站式解决方案

当下&#xff0c;传统媒体面临着诸多挑战&#xff0c;如何利用信息技术提升内容的质量、形式和分发效率&#xff0c;成为媒体行业的迫切需求。移动云作为数字中国建设的“主力军”&#xff0c; 立足于新兴媒体与云计算市场的变化与需求&#xff0c;推出了ONAIR 媒体云解决方案&…

HTTP/2

HTTP/2核心 二进制帧 HTTP 2.0中所有加强性能的核心带你在于此–二进制传输 之前的HTTP/1的版本中&#xff0c;传输数据方式–文本传输 在 HTTP 2.0 中&#xff0c;有两个非常重要的概念&#xff0c;分别是帧&#xff08;frame&#xff09;和流&#xff08;stream&#xff0…

vue2学习笔记(2/2)

vue2学习笔记&#xff08;1/2&#xff09; vue2学习笔记&#xff08;2/2&#xff09; 文章目录 1. 初始化脚手架2. 分析脚手架&render函数文件结构图示及说明main.jsindex.htmlApp.vueSchool.vueStudent.vue 关于不同版本的Vue修改默认配置vue.config.js配置文件 3. ref属…

点灯科技esp32 idfv5.1组件库

最近研究了一下点灯科技的app&#xff0c;看到官方提供的esp32 idf组件库支持v4.3/v4.4,所以就将其移植一下&#xff0c;让其支持v5.1版本&#xff0c;下载地址如下&#xff1a; https://github.com/guxiangguo/blinker-esp-idf_v5.1.git https://gitee.com/gu-xiangguo/blin…

08. 【Linux教程】CentOS 目录介绍

CentOS 目录介绍 前面小节介绍了如何安装并登录连接 CentOS 系统&#xff0c;本小节围绕 CentOS 系统的目录&#xff0c;介绍其各个目录的作用&#xff0c;方便读者以后在工作中很好地将项目和软件归类存储&#xff0c;熟悉 CentOS 系统各个目录的功能介绍&#xff0c;有助于加…

035 Arrays类

示例 int[] nums new int[10]; // fill Arrays.fill(nums, 666); System.out.println(Arrays.toString(nums)); // sort nums new int[]{1, 3, 5, 7, 9, 2, 4, 6, 8}; Arrays.sort(nums); System.out.println(Arrays.toString(nums)); // equals int[] nums2 new int[]{1,…

【数据分享】1929-2023年全球站点的逐日平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

【Spring】代理模式

文章目录 代理模式对代理模式的理解静态代理动态代理JDK动态代理原理源码优化 CGLIB动态代理使用原理 JDK与CGLIB的对比 面试题JDK动态代理和CGLIB有什么区别&#xff1f;既然有没有接口都可以用CGLIB&#xff0c;为什么Spring还要使用JDK动态代理&#xff1f; 代理模式 对代理…

关于自动驾驶概念的学习和一些理解

文章目录 对于自动驾驶的认识自动驾驶技术的优势自动驾驶的技术要求自动驾驶技术的挑战自动驾驶技术的潜在影响总结 对于自动驾驶的认识 自动驾驶是指车辆在没有人类驾驶员控制的情况下进行行驶的技术。随着人工智能的快速发展&#xff0c;自动驾驶技术已经成为将来交通行业的…

4. 树(二叉树、二叉查找树/二叉排序树/二叉搜索树、平衡二叉树、平衡二叉B树/红黑树)

树 1. 二叉树1.1 概述1.2 特点1.3 二叉树遍历方式1.3.1 前序遍历(先序遍历)1.3.2 中序遍历1.3.3 后序遍历1.3.4 层序遍历 2. 二叉查找树&#xff08;二叉排序树、二叉搜索树&#xff09;2.1 概述2.2 特点 3. 平衡二叉树3.1 概述3.2 特点3.3 旋转3.3.1 左旋3.3.2 右旋 3.4 平衡二…

云原生数据库 GaiaDB 的核心技术演进和解析

导读 在越来越强调云原生的环境下&#xff0c;存算分离作为一种新的架构理念&#xff0c;已经是大势所趋。新的技术架构带来新的问题和挑战&#xff0c;百度智能云的云原生数据库 GaiaDB 采用 Quorum 分布式协议、高性能网络、高可靠分布式存储引擎等技术实现更高的性能和可用性…

ElementUI Form:Select 选择器

ElementUI安装与使用指南 Select 选择器 点击下载learnelementuispringboot项目源码 效果图 el-select.vue&#xff08;Select选择器&#xff09;页面效果图 项目里el-select.vue代码 <script> export default {name: el_select,data() {return {options: [{value…

PHP之数据类型的基本介绍

让我为大家介绍一下PHP中的数据类型吧&#xff01; 数据类型有&#xff1a;字符串、整数、浮点数、布尔、数组、对象、NULL、资源类型 我们可以使用gettype去获取数据类型 var_jump()会返回变量的数据类型与值&#xff0c;一般用于开发调试时使用 字符串 字符串是字符序列…

备战蓝桥杯---搜索(优化1)

显然&#xff0c;我们可以用BFS解决&#xff0c;具体实现与八数码类似&#xff1a; 下面是代码&#xff1a; #include<bits/stdc.h> using namespace std; #define N 3000000 string a,b; int hh,dis[N],cnt; struct node{string u,v; }bian[7]; map<string,int>…

Python爬虫requests库详解

使用 requests 上一节中&#xff0c;我们了解了 urllib 的基本用法&#xff0c;但是其中确实有不方便的地方&#xff0c;比如处理网页验证和 Cookies 时&#xff0c;需要写 Opener 和 Handler 来处理。为了更加方便地实现这些操作&#xff0c;就有了更为强大的库 requests&…