【OpenGL学习】(四)统一着色和插值着色
文章目录
- 【OpenGL学习】(四)统一着色和插值着色
- 统一着色(Flat/Uniform Shading)
- 插值着色(Interpolated Shading)
【OpenGL学习】(四)统一着色和插值着色
着色器介绍:
https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/
统一着色(Flat/Uniform Shading)
统一着色下,所有像素使用相同的颜色,没有插值,不考虑光照、材质等细节。
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);// 窗口设置
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;// 顶点着色器源码
// 没有颜色输入,仅负责设置顶点位置
const char *vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n" // 位置属性"void main()\n""{\n"" gl_Position = vec4(aPos, 1.0);\n" // 设置最终裁剪空间位置"}\0";// 片段着色器源码
// 使用 uniform 统一变量接收颜色,实现统一着色
const char *fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n" // 输出颜色"uniform vec4 ourColor;\n" // uniform变量,全局统一颜色"void main()\n""{\n"" FragColor = ourColor;\n" // 所有像素都使用统一的 ourColor 值,即实现统一着色"}\n\0";int main()
{// 初始化 GLFWglfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // OpenGL 版本号设置为 3.3glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用核心模式#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 兼容 macOS
#endif// 创建窗口GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "创建 GLFW 窗口失败" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // 注册窗口大小变化回调// 初始化 GLADif (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化 GLAD 失败" << std::endl;return -1;}// 编译着色器// 顶点着色器unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);// 检查顶点着色器是否编译成功int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "错误::着色器::顶点::编译失败\n" << infoLog << std::endl;}// 片段着色器unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);// 检查片段着色器是否编译成功glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "错误::着色器::片段::编译失败\n" << infoLog << std::endl;}// 创建着色器程序并链接unsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// 检查着色器程序链接是否成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "错误::着色器::程序::链接失败\n" << infoLog << std::endl;}// 删除着色器对象,它们已经链接到程序中glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 顶点数据,三角形三个顶点坐标float vertices[] = {0.5f, -0.5f, 0.0f, // 右下角-0.5f, -0.5f, 0.0f, // 左下角0.0f, 0.5f, 0.0f // 顶部};unsigned int VBO, VAO;glGenVertexArrays(1, &VAO); // 顶点数组对象glGenBuffers(1, &VBO); // 顶点缓冲对象// 绑定 VAOglBindVertexArray(VAO);// 绑定 VBO,设置数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0); // 启用顶点属性// render loop 渲染循环while (!glfwWindowShouldClose(window)){// 处理输入processInput(window);// 清屏背景色glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// 激活着色器程序glUseProgram(shaderProgram);// ----------- 设置 uniform 变量实现统一着色 ------------// 获取时间值,用来动态变化颜色double timeValue = glfwGetTime();float greenValue = static_cast<float>(sin(timeValue) / 2.0 + 0.5);// 获取 uniform 变量位置int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");// 设置统一颜色为动态变化的绿色glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);// ----------------------------------------------------// 绘制三角形glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3);// 交换缓冲区,处理事件glfwSwapBuffers(window);glfwPollEvents();}// 删除资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate(); // 释放 GLFW 资源return 0;
}// 处理输入事件:按下 ESC 键关闭窗口
void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// 视口调整回调
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// 调整视口大小以匹配窗口大小glViewport(0, 0, width, height);
}
程序通过以下步骤实现统一着色:
-
片段着色器中定义了 uniform 变量:
uniform vec4 ourColor;
这是一个全局变量,作用于所有像素(片段)。
-
片段着色器统一使用该颜色输出:
FragColor = ourColor;
-
通过 glUniform4f() 设置颜色值:
// ----------- 设置 uniform 变量实现统一着色 ------------// 获取时间值,用来动态变化颜色double timeValue = glfwGetTime();float greenValue = static_cast<float>(sin(timeValue) / 2.0 + 0.5);// 获取 uniform 变量位置int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");// 设置统一颜色为动态变化的绿色glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);// ----------------------------------------------------
插值着色(Interpolated Shading)
插值着色下,各个像素的颜色是根据各个顶点的颜色进行插值得到的。
#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>// 当窗口大小发生变化时,调整视口
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}// 处理输入:按下ESC键关闭窗口
void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// 设置窗口尺寸
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;// 顶点着色器源码
const char *vertexShaderSource = R"glsl(
#version 330 core
layout (location = 0) in vec3 aPos; // 顶点位置
layout (location = 1) in vec3 aColor; // 顶点颜色out vec3 ourColor; // 输出变量,将传递给片段着色器void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor; // 将每个顶点的颜色传递给片段着色器
}
)glsl";// 片段着色器源码
const char *fragmentShaderSource = R"glsl(
#version 330 core
in vec3 ourColor; // 从顶点着色器传入的颜色(已插值)out vec4 FragColor;void main()
{FragColor = vec4(ourColor, 1.0); // 使用插值后的颜色作为输出颜色
}
)glsl";int main()
{// 初始化并配置GLFWglfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // OpenGL主版本号glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // OpenGL次版本号glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用核心模式#ifdef __APPLE__glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Mac OS X需要
#endif// 创建窗口GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "插值着色示例", NULL, NULL);if (window == NULL){std::cout << "创建GLFW窗口失败" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);// 设置窗口尺寸变化的回调函数glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// 初始化GLAD,加载OpenGL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化GLAD失败" << std::endl;return -1;}// 编译顶点着色器unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); // 创建顶点着色器对象glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // 附加着色器源码glCompileShader(vertexShader); // 编译着色器// 检查编译是否成功int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::顶点着色器::编译失败\n" << infoLog << std::endl;}// 编译片段着色器unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // 创建片段着色器对象glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); // 附加着色器源码glCompileShader(fragmentShader); // 编译着色器// 检查编译是否成功glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::片段着色器::编译失败\n" << infoLog << std::endl;}// 链接着色器程序unsigned int shaderProgram = glCreateProgram(); // 创建程序对象glAttachShader(shaderProgram, vertexShader); // 附加顶点着色器glAttachShader(shaderProgram, fragmentShader); // 附加片段着色器glLinkProgram(shaderProgram); // 链接程序// 检查链接是否成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::着色器程序::链接失败\n" << infoLog << std::endl;}// 删除着色器对象,它们已经链接到程序中,不再需要glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 设置顶点数据和缓冲,并配置顶点属性float vertices[] = {// 位置 // 颜色0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下角,红色-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下角,绿色0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部,蓝色};unsigned int VBO, VAO;glGenVertexArrays(1, &VAO); // 生成顶点数组对象glGenBuffers(1, &VBO); // 生成顶点缓冲对象// 绑定顶点数组对象glBindVertexArray(VAO);// 绑定顶点缓冲对象glBindBuffer(GL_ARRAY_BUFFER, VBO);// 将顶点数据复制到缓冲中glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 设置顶点位置属性指针// 参数说明:// 0 - 指定要修改的顶点属性的位置值(与顶点着色器中的layout(location=0)对应)// 3 - 每个顶点属性由3个分量组成(x,y,z坐标)// GL_FLOAT - 数据类型为GLfloat(32位浮点数)// GL_FALSE - 表示不需要对数据进行归一化处理// 6 * sizeof(float) - stride(步长),表示连续顶点之间的字节偏移量// 这里每个顶点有6个float(3个位置+3个颜色)// (void*)0 - 起始偏移量,表示位置数据从缓冲区的开头开始glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);// 启用顶点属性数组0(位置属性)// 必须调用此函数才能使能顶点属性数组,否则该属性不会被使用glEnableVertexAttribArray(0);// 设置顶点颜色属性指针// 参数说明:// 1 - 指定要修改的顶点属性的位置值(与顶点着色器中的layout(location=1)对应)// 3 - 每个顶点属性由3个分量组成(r,g,b颜色)// GL_FLOAT - 数据类型为GLfloat(32位浮点数)// GL_FALSE - 表示不需要对数据进行归一化处理// 6 * sizeof(float) - 相同的stride值,因为顶点数据是交错排列的// (void*)(3 * sizeof(float)) - 起始偏移量,表示颜色数据从第4个float开始// (前3个float是位置数据)glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));// 启用顶点属性数组1(颜色属性)glEnableVertexAttribArray(1);// 使用着色器程序glUseProgram(shaderProgram);// 渲染循环while (!glfwWindowShouldClose(window)){// 处理输入processInput(window);// 清除颜色缓冲glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 设置清除颜色glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲// 绘制三角形glBindVertexArray(VAO); // 绑定VAOglDrawArrays(GL_TRIANGLES, 0, 3); // 绘制三角形// 交换缓冲区并查询IO事件glfwSwapBuffers(window);glfwPollEvents();}// 可选:释放资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);// 终止GLFW,清理资源glfwTerminate();return 0;
}
在OpenGL中,跨着色器传递数据需在发送方声明out
变量,接收方声明匹配的in
变量(同名同类型)。链接程序时,OpenGL会自动关联这些变量,实现数据传输。
顶点着色器:
const char *vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n" // 顶点位置输入"layout (location = 1) in vec3 aColor;\n" // 顶点颜色输入"out vec3 ourColor;\n" // 输出变量,将传递给片段着色器"void main()\n""{\n"" gl_Position = vec4(aPos, 1.0);\n" // 设置顶点位置" ourColor = aColor;\n" // 将顶点颜色赋值给输出变量"}\0";
片段着色器:
const char *fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n" // 最终输出的片段颜色"in vec3 ourColor;\n" // 接收从顶点着色器传来的插值颜色"void main()\n""{\n"" FragColor = vec4(ourColor, 1.0f);\n" // 使用插值后的颜色作为片段颜色"}\n\0";
顶点着色器将每个顶点的颜色信息通过 out
变量 ourColor
传递给片段着色器,片段着色器再通过 in
变量 ourColor
接收该信息。
在主程序中,顶点数据需要包括位置和颜色信息:
float vertices[] = {// 位置 // 颜色0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下角,红色-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下角,绿色0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部,蓝色
};
渲染三角形时,OpenGL 会自动为三角形内的每一个片段自动计算 ourColor 的插值值(基于顶点的颜色和片段在三角形内的位置)。
相关文章:

【OpenGL学习】(四)统一着色和插值着色
文章目录 【OpenGL学习】(四)统一着色和插值着色统一着色(Flat/Uniform Shading)插值着色(Interpolated Shading) 【OpenGL学习】(四)统一着色和插值着色 着色器介绍: h…...
42、响应处理-【源码分析】-浏览器与PostMan内容协商完全适配
42、响应处理源码分析浏览器与PostMan内容协商完全适配 要实现浏览器与PostMan在内容协商上的完全适配,需要在Spring Boot应用中自定义内容协商策略,确保服务器能根据浏览器和PostMan的请求头正确返回合适格式的数据。以下是详细的步骤: ### …...

在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源
在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源,可以加速镜像下载速度。以下是详细的步骤: 一、安装 Docker 移除旧版本的 Docker(如果有): sudo yum remove docker \docker-client \docker-client…...
Java Lambda表达式深度解析:从入门到实战
简介 Lambda表达式是Java 8引入的最重要特性之一,它极大地简化了Java代码的编写方式,使函数式编程风格在Java中成为可能。本文将全面介绍Lambda表达式的概念、语法、应用场景以及与相关特性的配合使用,帮助开发者掌握这一强大的编程工具。 一、Lambda表达式基础 1.1 什么…...

Docker慢慢学
1、Docker DeskTop 2、N8N下载 docker run -p 8888:5678 n8nio/n8n 3、Kafka kafka依赖zookeeper,先启动zookeeper docker pull zookeeper docker run -d --name zookeeper -p 2181:2181 -e ALLOW_ANONYMOUS_LOGINyes zookeeper 启动kafka docker pull confluentinc/cp…...

cursor-free-vip使用
一、项目简介 Cursor-Free-VIP 是一个开源项目,旨在帮助用户免费使用 Cursor AI 的高级功能。它通过自动注册 Cursor 账号、重置机器 ID 和完成 Auth 验证等操作,解决 Cursor AI 中常见的限制提示。 二、系统准备 1…cursor需要更新到最新的版本 三、…...

使用SSH tunnel访问内网的MySQL
文章目录 环境背景方法参考 注:本文是使用SSH tunnel做端口转发的一个示例。有关SSH端口转发,可参考我的几篇文档 https://blog.csdn.net/duke_ding2/article/details/106878081https://blog.csdn.net/duke_ding2/article/details/135627263https://blo…...

Redis持久化模式RDB与AOF
RDB持久化 RDB也被叫做Redis数据快照。简单来说就是把内存中的所有数据记录到磁盘中。当Redis实例故障重启后重磁盘中读取快照文件进行数据恢复(快照文件默认保存在当前运行目录); 演示Redis正常停机自动执行一次RDB操作 配置Redis触发RDB机制 RDB其它配置也可在red…...
【JS进阶】ES5 实现继承的几种方式
ES5 实现继承的几种方式 1. 原型链继承(Prototype Chaining) function Parent(name) {this.name name || Parent;this.colors [red, blue]; }Parent.prototype.sayName function() {console.log(this.name); };function Child() {}// 关键ÿ…...

【数据结构】树形结构--二叉树(二)
【数据结构】树形结构--二叉树(二) 一.二叉树的实现1.求二叉树结点的个数2.求二叉树叶子结点的个数3.求二叉树第k层结点的个数4.求二叉树的深度(高度)5.在二叉树中查找值为x的结点6.判断二叉树是否为完全二叉树7.二叉树的销毁 一.…...
JavaScript性能优化实战:深入探讨JavaScript性能瓶颈与优化技巧
引言:为什么JavaScript性能至关重要 在现代Web开发中,JavaScript已成为构建交互式应用程序的核心技术。随着单页应用(SPA)和复杂前端架构的普及,JavaScript代码的性能直接影响用户体验、转化率甚至搜索引擎排名。研究表明,页面加载时间每增加1秒,转化率可能下降7%,而性能…...
在 CentOS 上将 Ansible 项目推送到 GitHub 的完整指南
1. 安装 Git 在 CentOS 中使用 yum 安装 Git,Git 是管理代码版本控制的工具: sudo yum install git -y 2. 配置 Git 用户信息 设置你的 Git 用户名和邮箱,这些信息会出现在你每次提交的记录中: git config --global user.nam…...

深度学习题目1
梯度下降法的正确步骤是什么? a.计算预测值和真实值之间的误差 b.重复迭代,直至得到网络权重的最佳值 c.把输入传入网络,得到输出值 d.用随机值初始化权重和偏差 e.对每一个产生误差的神经元,调整相应的(权重ÿ…...
Spring @Scheduled vs XXL-JOB vs DolphinScheduler vs Airflow:任务调度框架全景对比
引言 从单机定时任务到分布式工作流调度,不同场景需要选择匹配的调度框架。 本文对比 Spring Scheduled、XXL-JOB、DolphinScheduler (海豚调度器)和 Apache Airflow 的核心差异,助你避免过度设计或功能不足。 一、核心定位与适用…...

【Oracle】锁
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 锁基础概述1.1 锁的概念与作用1.2 锁的工作原理1.3 Oracle锁的分类 2. 行级锁 (Row-Level Locks)2.1 行级锁的基本概念2.1.1 TX锁(事务锁)2.1.2 行级锁的工作机制 2.2 行级锁的类型2.…...
共识算法Raft系列(1)——什么是Raft?
Raft 算法是一种分布式一致性算法,由 Diego Ongaro 和 John Ousterhout 在 2014 年提出,旨在解决 Paxos 算法复杂且难以理解的问题。Raft 设计目标是易于理解和实现,同时提供强一致性(CAP 中的 CP 系统),广…...

JS逆向爬虫教程与实战技巧
想要一个关于爬虫JS逆向的详细教程。这是一个很专业的技术需求,最近有个可能是正在学习爬虫技术的开发者或者数据分析师,遇到了需要破解JavaScript加密的反爬机制的问题,想让我出一期实战教程,话不多说,开干。 以下是我…...
Neovim - LSP 底层原理,难点配置(二)
Neovim LSP 的工作原理 基本概念 LSP(Language Server Protocol)可以理解成是一个"语言助手"。每种编程语言都有自己的"语言助手"(比如 TypeScript 的 tsserver),这些助手能告诉你: 哪写错了(语法错误)哪能跳转(方法定义,引用)哪可以补全(自…...

【Redis】Redis 的常见客户端汇总
目录 一、命令行客户端 二、图形界面的客户端 三、Java 客户端 3.1 SpringDataRedis 3.2 Jedis 3.2.1 连接池的配置 3.3 Lettuce 3.3.1 RedisTemplate 工具类实现 3.3.2 自定义序列化器 3.3.3 StringRedisTemplate 3.3.4 集群配置 3.3.4.1 刷新节点集群拓扑动态感应…...

关于akka官方quickstart示例程序(scala)的记录
参考资料 https://doc.akka.io/libraries/akka-core/current/typed/actors.html#first-example 关于scala语法的注意事项 extends App是个语法糖,等同于直接在伴生对象中编写main 方法对象是通过apply方法创建的,也可以通过对象的名称单独创建&#x…...

2025年渗透测试面试题总结-腾讯[实习]玄武实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]玄武实验室-安全工程师 1. 自我介绍 2. CSRF原理 3. Web安全入门时间 4. 学习Web安全的原因 …...

网站首页菜单两种布局vue+elementui顶部和左侧栏导航
顶部菜单实现 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Vue.js Element UI 路由导航</…...
AWS之迁移与传输服务
目录 一、迁移管理与规划类 二、应用程序迁移类 1. MGN的迁移范围(能替代的场景) ✅ 自动包含以下数据: 🔹 适用场景举例: 2. 仍需DMS或DataSync的场景(不可替代) ❌ DMS仍必要的情况: ❌ DataSync仍必要的情况: 3. 技术原理对比 MGN的数据迁移机制: DMS…...

@Builder的用法
Builder 是 Lombok 提供的一个注解,用于简化 Java 中构建对象的方式(Builder 模式)。它可以让你以更加简洁、链式的方式来创建对象,尤其适用于构造参数较多或部分可选的类。...
Unity3D 逻辑代码性能优化策略
前言 在Unity3D中优化逻辑代码性能是提升游戏流畅度的关键。以下是系统性的优化策略和示例: 对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀! 1. 避免高频操作中的开销 缓存组件引用 private …...
【Python Cookbook】文件与 IO(二)
文件与 IO(二) 6.字符串的 I/O 操作7.读写压缩文件8.固定大小记录的文件迭代(⭐⭐) 6.字符串的 I/O 操作 你想使用操作类文件对象的程序来操作文本或二进制字符串。 使用 io.StringIO() 和 io.BytesIO() 类来创建类文件对象操作…...

vue实现点击按钮input保持聚焦状态
主要功能: 点击"停顿"按钮切换对话框显示状态输入框聚焦时保持状态点击对话框外的区域自动关闭 以下是代码版本: <template><div class"input-container"><el-inputv-model"input"style"width: 2…...

[蓝桥杯]取球博弈
取球博弈 题目描述 两个人玩取球的游戏。 一共有 NN 个球,每人轮流取球,每次可取集合 n1,n2,n3n1,n2,n3中的任何一个数目。 如果无法继续取球,则游戏结束。 此时,持有奇数个球的一方获胜。 如果两人都是奇数ÿ…...
Spring Security入门:创建第一个安全REST端点项目
项目初始化与基础配置 创建基础Spring Boot项目 我们首先创建一个名为ssia-ch2-ex1的空项目(该名称与配套源码中的示例项目保持一致)。项目需要添加以下两个核心依赖: org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-secur…...

[Java 基础]数组
什么是数组?想象一下,你需要存储 5 个学生的考试成绩。你可以声明 5 个不同的 int 变量,但这会显得很笨拙。数组提供了一种更简洁、更有组织的方式来存储和管理这些数据。 数组可以看作是相同类型元素的集合,这些元素在内存中是连…...