Android OpenGL ES详解——颜色

手把手教你用Android OpenGLES2.0实现FBO离屏截图功能(含GLSL代码) 本文详细介绍了如何使用Android OpenGLES2.0实现FBO(Frame Buffer Object)离屏截图功能,包括核心原理、完整实现流程和高级应用场景。通过GLSL代码示例和性能优化建议,帮助开发者掌握离屏渲染技术,提升移动端图形处理能力。 阅读详情

目录

一、颜色的概念

1、颜色的组成分量

2、物体的颜色——反射颜色

3、计算反射颜色

二、颜色应用——模拟光照场景


一、颜色的概念

1、颜色的组成分量

在前面的教程中我们已经简要提到过该如何在OpenGL中使用颜色(Color),但是我们至今所接触到的都是很浅层的知识。本节我们将会更广泛地讨论颜色,并且还会为接下来的光照(Lighting)教程创建一个场景。

现实世界中有无数种颜色,每一个物体都有它们自己的颜色。我们要做的工作是使用(有限的)数字来模拟真实世界中(无限)的颜色,因此并不是所有的现实世界中的颜色都可以用数字来表示。然而我们依然可以用数字来代表许多种颜色,并且你甚至可能根本感觉不到他们与真实颜色之间的差异。颜色可以数字化的由红色(Red)、绿色(Green)和蓝色(Blue)三个分量组成,它们通常被缩写为RGB。这三个不同的分量组合在一起几乎可以表示存在的任何一种颜色。例如,要获取一个珊瑚红(Coral)颜色我们可以这样定义一个颜色向量:

glm::vec3 coral(1.0f, 0.5f, 0.31f);

2、物体的颜色——反射颜色

我们在现实生活中看到某一物体的颜色并不是这个物体的真实颜色,而是它所反射(Reflected)的颜色。换句话说,那些不能被物体吸收(Absorb)的颜色(被反射的颜色)就是我们能够感知到的物体的颜色。例如,太阳光被认为是由许多不同的颜色组合成的白色光(如下图所示)。如果我们将白光照在一个蓝色的玩具上,这个蓝色的玩具会吸收白光中除了蓝色以外的所有颜色,不被吸收的蓝色光被反射到我们的眼中,使我们看到了一个蓝色的玩具。下图显示的是一个珊瑚红的玩具,它以不同强度的方式反射了几种不同的颜色。

正如你所见,白色的阳光是一种所有可见颜色的集合,上面的物体吸收了其中的大部分颜色,它仅反射了那些代表这个物体颜色的部分,这些被反射颜色的组合就是我们感知到的颜色(此例中为珊瑚红)。

3、计算反射颜色

这些颜色反射的规律被直接地运用在图形领域。我们在OpenGL中创建一个光源时都会为它定义一个颜色。在前面的段落中所提到光源的颜色都是白色的,那我们就继续来创建一个白色的光源吧。当我们把光源的颜色与物体的颜色相乘,所得到的就是这个物体所反射该光源的颜色(也就是我们感知到的颜色)。让我们再次审视我们的玩具(这一次它还是珊瑚红)并看看如何计算出他的反射颜色。我们通过检索结果颜色的每一个分量来看一下光源色和物体颜色的反射运算:

glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (1.0f, 0.5f, 0.31f);

我们可以看到玩具在进行反射时吸收了白色光源颜色中的大部分颜色,但它对红、绿、蓝三个分量都有一定的反射,反射量是由物体本身的颜色所决定的。这也代表着现实中的光线原理。由此,我们可以定义物体的颜色为这个物体从一个光源反射各个颜色分量的多少。现在,如果我们使用一束绿色的光又会发生什么呢?

glm::vec3 lightColor(0.0f, 1.0f, 0.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (0.0f, 0.5f, 0.0f);

可以看到,我们的玩具没有红色和蓝色的光让它来吸收或反射,这个玩具也吸收了光线中一半的绿色,当然它仍然反射了光的一半绿色。它现在看上去是深绿色(Dark-greenish)的。我们可以看到,如果我们用一束绿色的光线照来照射玩具,那么只有绿色能被反射和感知到,没有红色和蓝色能被反射和感知。这样做的结果是,一个珊瑚红的玩具突然变成了深绿色物体。现在我们来看另一个例子,使用深橄榄绿色(Dark olive-green)的光线:

glm::vec3 lightColor(0.33f, 0.42f, 0.18f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (0.33f, 0.21f, 0.06f);

如你所见,我们可以通过物体对不同颜色光的反射来的得到意想不到的不到的颜色,从此创作颜色已经变得非常简单。

目前有了这些颜色相关的理论已经足够了,接下来我们将创建一个场景用来做更多的实验。

二、颜色应用——模拟光照场景

在接下来的教程中,我们将通过模拟真实世界中广泛存在的光照和颜色现象来创建有趣的视觉效果。现在我们将在场景中创建一个看得到的物体来代表光源,并且在场景中至少添加一个物体来模拟光照。

首先我们需要一个物体来投光(Cast the light),我们将使用前面教程中的立方体箱子。我们还需要一个物体来代表光源,它代表光源在这个3D空间中的确切位置。简单起见,我们依然使用一个立方体来代表光源。

当然,填一个顶点缓冲对象(VBO),设定一下顶点属性指针和其他一些东西现在对你来说应该很容易了,所以我们就不再赘述那些步骤了。如果你仍然觉得这很困难,我建议你复习之前的教程,并且在继续学习之前先把练习过一遍。

所以,我们首先需要一个顶点着色器来绘制箱子。与上一个教程的顶点着色器相比,容器的顶点位置保持不变(虽然这一次我们不需要纹理坐标),因此顶点着色器中没有新的代码。我们将会使用上一篇教程顶点着色器的精简版:

#version 330 core
layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(position, 1.0f);
}

请确认更新你的顶点数据和属性对应的指针与新的顶点着色器一致。

因为我们还要创建一个表示灯(光源)的立方体,所以我们还要为这个灯创建一个特殊的VAO。当然我们也可以让这个灯和其他物体使用同一个VAO然后对他的model(模型)矩阵做一些变换,然而接下来的教程中我们会频繁地对顶点数据做一些改变并且需要改变属性对应指针设置,我们并不想因此影响到灯(我们只在乎灯的位置),因此我们有必要为灯创建一个新的VAO。

GLuint lightVAO;
glGenVertexArrays(1, &lightVAO);
glBindVertexArray(lightVAO);
// 只需要绑定VBO不用再次设置VBO的数据,因为容器(物体)的VBO数据中已经包含了正确的立方体顶点数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 设置灯立方体的顶点属性指针(仅设置灯的顶点数据)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);

这段代码对你来说应该非常直观。既然我们已经创建了表示灯和被照物体的立方体,我们只需要再定义一个东西就行了了,那就是片段着色器

#version 330 core
out vec4 color;

uniform vec3 objectColor;
uniform vec3 lightColor;

void main()
{
    color = vec4(lightColor * objectColor, 1.0f);
}

这个片段着色器接受两个分别表示物体颜色和光源颜色的uniform变量。正如本篇教程一开始所讨论的一样,我们将光源的颜色与物体(能反射)的颜色相乘。这个着色器应该很容易理解。接下来让我们把物体的颜色设置为上一节中所提到的珊瑚红并把光源设置为白色:

// 在此之前不要忘记首先'使用'对应的着色器程序(来设定uniform)
GLint objectColorLoc = glGetUniformLocation(lightingShader.Program, "objectColor");
GLint lightColorLoc  = glGetUniformLocation(lightingShader.Program, "lightColor");
glUniform3f(objectColorLoc, 1.0f, 0.5f, 0.31f);// 我们所熟悉的珊瑚红
glUniform3f(lightColorLoc,  1.0f, 1.0f, 1.0f); // 依旧把光源设置为白色

要注意的是,当我们修改顶点或者片段着色器后,灯的位置或颜色也会随之改变,这并不是我们想要的效果。我们不希望灯对象的颜色在接下来的教程中因光照计算的结果而受到影响,而希望它能够独立。希望表示灯不受其他光照的影响而一直保持明亮(这样它才更像是一个真实的光源)。

为了实现这个目的,我们需要为灯创建另外的一套着色器程序,从而能保证它能够在其他光照着色器变化的时候保持不变。顶点着色器和我们当前的顶点着色器是一样的,所以你可以直接把灯的顶点着色器复制过来。片段着色器保证了灯的颜色一直是亮的,我们通过给灯定义一个常量的白色来实现:

#version 330 core
out vec4 color;

void main()
{
    color = vec4(1.0f); //设置四维向量的所有元素为 1.0f,灯光颜色为常量白色
}

当我们想要绘制我们的物体的时候,我们需要使用刚刚定义的光照着色器绘制箱子(或者可能是其它的一些物体),让我们想要绘制灯的时候,我们会使用灯的着色器。在之后的教程里我们会逐步升级这个光照着色器从而能够缓慢的实现更真实的效果。

使用这个灯立方体的主要目的是为了让我们知道光源在场景中的具体位置。我们通常在场景中定义一个光源的位置,但这只是一个位置,它并没有视觉意义。为了显示真正的灯,我们将表示光源的灯立方体绘制在与光源同样的位置。我们将使用我们为它新建的片段着色器让它保持它一直处于白色状态,不受场景中的光照影响。

我们声明一个全局vec3变量来表示光源在场景的世界空间坐标中的位置:

glm::vec3 lightPos(1.2f, 1.0f, 2.0f);

然后我们把灯平移到这儿,当然我们需要对它进行缩放,让它不那么明显:

model = glm::mat4();
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f));

绘制灯立方体的代码应该与下面的类似:

lampShader.Use();
// 设置模型、视图和投影矩阵uniform
...
// 绘制灯立方体对象
glBindVertexArray(lightVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);

请把上述的所有代码片段放在你程序中合适的位置,这样我们就能有一个干净的光照实验场地了。如果一切顺利,运行效果将会如下图所示:

现在我们有了一些关于颜色的知识,并且创建了一个基本的场景能够绘制一些漂亮的光线。

参考文章

颜色 - LearnOpenGL-CN

Android openGl开发详解(一)——绘制简单图形 1. What? openGl是什么?openGl ES又是什么? 2. How? Android中的openGL 如何使用? 3. GlSurfaceView是什么? GLSurfaceView的作用是什么? GLSurfaceView如何使用? 4. GlSurfaceView.Renderer是什么?GLSurfaceView.Renderer的作用?GLSurfaceView.Re... 阅读详情

相关推荐

Android OpenGL ES学习笔记之实现OpenGL ES接口

一、GLSurfaceView介绍 在Android平台上实现OpenGL的view很简单,只需要用到GLSurfaceView和GLSurfaceView.Renderer。 GLSurfaceView是用来连接OpenGL ES和android的view结构的.GLSurfaceView位于android.opengl包类,继承自SurfaceView public class GL

Dennis-Android的博客 4918

OpenGL入门学习(四) 【转】

 OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式。无论哪种颜色模式,计算机都必须为每一个像素保存一些数据。不同的是,RGBA模式中,数据直接就代表了颜色;而颜色索引模式中,数据代表的是一个索引,要得到真正的颜色,还必须去查索引表。1. RGBA颜色RGBA模式中,每一个像素会保存以下数据:R值(红色分量)、G值(绿色分量)、B值(蓝色分量)和A值(alpha分量)。其中红、绿、蓝

shiqx429的专栏 1680

android opengl es基本操作,画线,三角形,正方形,颜色设置

上篇文章讲了opengl es的基本知识,GLSurfaceView的创建,画点等内容,这篇文章将opengl es另外的一些基本操作,比如画线,画三角形,正方形等,以及这些例子中涉及到了相关的知识点。      1、画线,画线的操作和点差不多,具体看如下代码     public void DrawLine(GL10 gl) {         ByteBuffer vbb

u012761326的博客 5627

OpenGL基础图形编程 - OpenGL颜色

几乎所有OpenGL应用目的都是在屏幕窗口内绘制彩色图形,所以颜色在OpenGL编程中占有很重要的地位。这里的颜色与绘画中的颜色概念不一样,它属于RGB颜色空间,只在监视器屏幕上显示。另外,屏幕窗口坐标是以象素为单位,因此组成图形的每个象素都有自己 的颜色,而这种颜色值是通过对一系列OpenGL函数命令的处理最终计算出来的。本章将讲述计算机颜色的概念以及OpenGL的颜色模式、颜色定义和两种模式应

popkiler的专栏 3042

Android Studio + OpenGL ES 学习记录

Android Studio + OpenGL ES 学习记录 OpenGL是一种应用程序编程接口,它是一种可以对图形硬件设备特性进行访问的软件库,而OpenGL ES是OpenGL的子集,针对手机、PDA和游戏主机嵌入式设备而设计。OpenGL ES 是从 OpenGL 裁剪定制而来的,去除了 glBegin/glEnd,四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性,剩下最核心有用的部分。 简介 OpenGL是用于渲染2D、3D矢量图形的跨语言、跨平台的应用

huhfairy的博客 3015

OpenGL ES EGL介绍

前面已经在android平台上使用OpenGL ES的API了解了如何创建3D图形已经使用FBO渲染到纹理进行一些其他的操作,起初我学习OpenGL ES的目的就是为了研究Android平台上录制屏幕的方案。到目前为止,基础知识已经具备了,还差一点需要了解的是Embedded Graphics Library (EGL),EGL是连接OpenGL ES和本地窗口系统的接口,由于OpenGL ES是跨

weiersyuan的专栏 1万+

OpenGL学习之颜色

一、颜色的表示 颜色纺锤体(颜色锥体) 颜色的视觉模型:颜色三特性的空间表示 明度(亮度):垂直轴线表示黑白亮度变化 色调:水平圆周上的不同角度点,代表了不同色调的颜色 饱和度:从圆心向圆周过渡表示,同一色调下饱和度的提高。某个平面圆形上的色调饱和度不同,而明度(亮度)相同。 CIE(Commission...

Estelle 1851

OpenGL ES中YUV转RGB的顶点与片元着色器实现详解

顶点属性是GPU渲染流程中最基础的数据单元,它决定了每个顶点携带的信息类型和组织方式。对于全屏图像渲染而言,通常只需要两个核心属性:顶点位置(position)和纹理坐标(texCoord)。这两者共同构成了OpenGL ES中用于绘制矩形或三角形条带的基本语义框架。

weixin_35916518的博客 852

13_LearnOpenGL 光照

在前面的教程中我们已经简要提到过该如何在OpenGL中使用颜色(Color),但是我们至今所接触到的都是很浅层的知识。本节我们将会更广泛地讨论颜色,并且还会为接下来的光照(Lighting)教程创建一个场景。现实世界中有无数种颜色,每一个物体都有它们自己的颜色。我们要做的工作是使用(有限的)数字来模拟真实世界中(无限)的颜色,因此并不是所有的现实世界中的颜色都可以用数字来表示。然而我们依然可以用数字来代表许多种颜色,并且你甚至可能根本感觉不到他们与真实颜色之间的差异。

成长需要沉淀。 1135

OpenGL里面的一些颜色设置和图形绘制用的函数

有个是 颜色的 设置。 还有一个 就是 正方形,正方体,多边体,茶壶 之类的 辅助函数

opengl贴图与颜色混合

opengl贴图与颜色混合, 完整代码,有位图资源。

OpenGL(九)——颜色

我们看到的物体颜色是通过光照在物体,然后反射到人眼成像,具体而言是物体不能吸收的颜色。如白光照射在蓝色物体上,它吸收了除了蓝光之外所有颜色,不吸收的蓝光反射到我们眼中。当物体颜色是多色光组合时(珊瑚色),该物体会反射不同强度的多个颜色,最终形成(珊瑚色)。

GZ的博客 1523

鸿蒙读书笔记1:《鸿蒙操作系统设计原理与架构》

GUI、 语 音 控 制 方 式 的 VUI(Voice User Interface, 语 音 用 户 界。电话、多媒体、DFX、MSDP(Multimodal Sensor Data Platform,多。面)、手势/姿态控制的CVUI(Computer Vision User Interface,计算。KAL(Kernel Abstract Layer,内核抽象层)通过屏蔽多内核差异,JavaScript、C、C++等多语言的用户程序开发框架,以及UI框架、

jackyrongvip的专栏 2446

Android OpenGL ES学习笔记之添加颜色

一、分类 添加颜色的种类有两种 - Flat coloring 单色 - Smooth coloring 平滑着色 单色 顾命思义就是一种单一的颜色,调用 glColor4f(float red, float green, float blue, float alpha)方法传入红、绿、蓝、透明度四个参数,取值0~1f。 还是以An

Dennis-Android的博客 4147

baostock实战:如何用Python批量下载多只股票的历史数据(含常见错误排查)

本文详细介绍了如何使用Python和baostock库批量下载多只股票的历史数据。内容涵盖从环境搭建、代码标准化到构建稳健的批量下载框架的全过程,并重点提供了高级错误处理、网络重试、数据验证及内存管理等实战解决方案,帮助用户高效构建股票数据处理流水线。

nice1的博客 1081

kettle写doris操作

文件在目录:doris-master\extension\kettle\assemblies\plugin\target\doris-stream-loader-plugins-9.4.0.0-343.zip。官方提供了doris stream load插件,下载源码编译后放到kettle的插件目录即可使用。地址:https://github.com/apache/doris.git。注意:需要doris插件或者kettle转换生成模板的私聊博主。使用PDmaner同步业务库生成建表语句。

weixin_44449054的博客 3028

Android仿彩色弥散(Siri)效果实现与性能优化实战

基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。架构理解:掌握实时语音应用的完整技术链路(ASR→LLM→TTS)技能提升:学会申请、配置与调用火山引擎AI服务定制能力:通过代码修改自定义角色性格与音色,实现“从使用到创造”从0到1构建生产级别应用,脱离Demo,点击打开。

2600_94959849的博客 290

QMT量化交易实战:如何用通达信预警数据自动买卖股票(附完整Python代码)

本文详细介绍了如何利用QMT平台结合通达信预警数据实现股票自动化交易,提供完整的Python代码实现。通过实时监控通达信预警板块文件,系统自动执行买卖操作,提升交易效率。文章涵盖系统架构设计、数据对接、信号处理、订单执行等核心模块,适合量化交易初学者和通达信用户参考实践。

weixin_29251567的博客 677

Immich 自托管照片与视频管理方案:架构解析、Docker 部署与功能全景

Immich 是一个高性能的自托管(self-hosted)照片与视频管理方案,本文基于仓库根目录 README 展开,结合 `docker/` 部署配置、`docs/docs/` 官方文档与 `server/`、`machine-learning/` 等源码实现,完整讲解 Immich 的部署方式、核心环境变量、后台服务架构与全量功能矩阵。读完本文,你将能够独立完成 Immich 的 Docke

gitblog_00654的博客 713

解题报告-美团点评2017秋招笔试编程题--常见动态规划问题

晚上就要美团笔试了,在牛客上刷套美团的题练练手,四道题目全都是典型题目,经典的连题面都懒得改那种,也都不难,很基础的动态规划问题。[编程题] 大富翁游戏时间限制:1秒空间限制:32768K大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法。 输...

聂小白的专栏 1718

SimNow模拟环境实战:用vnpy_ctp连接期货市场的5个关键配置步骤

本文提供了一份详细的量化交易实战指南,重点讲解如何使用vnpy_ctp插件连接SimNow期货模拟环境的5个关键配置步骤。内容涵盖SimNow环境选择、vnpy_ctp核心参数解析、实战连接脚本编写、深度排错技巧以及向实盘迁移的准备,旨在帮助量化交易开发者快速搭建可靠的测试环境,避免常见陷阱。

weixin_29063035的博客 1271

android opengl es 雾化效果

<br /> <br />雾效果其实很容易实现,我先总结一下:<br />(1)首先肯定是将背景色设为我们雾的颜色<br />(2)打开雾效果<br />(3)设置雾的背景色<br />(4)设置雾方程式<br />雾方程式有三种表现形式 EXP(最老),EXP2(EXP加强版),LINEAR(雾的最好方程式,当然用这个),如果要用LINEAR这种,则要多雾start,end的设置,表示雾从多远开始,从多远停止 。像LINEAR这种称之为线性雾(不是我发明的,OPENGL超级宝典上这样说,设置稠密度无效)

Simdanfeg的专栏 6685

【S32K3 MCAL配置】-3.4-CANFD配置-接收特定的“经典CAN/CANFD标准帧”和“经典CAN/CANFD扩展帧”(基于MCAL+FreeRTOS)

【S32K3 MCAL配置】-3.4-CANFD配置-接收特定的“经典CAN/CANFD标准帧”和“经典CAN/CANFD扩展帧”(基于MCAL+FreeRTOS)

「汽车电子助手」的博客 695

Android OpenGL ES 开发教程(20):颜色Color

OpenGL ES 支持的颜色格式为RGBA模式(红,绿,蓝,透明度)。颜色的定义通常使用Hex格式0xFF00FF 或十进制格式(255,0,255), 在OpenGL 中却是使用0…1之间的浮点数表示。 0为0,1相当于255(0xFF)。 我们在Android OpenGL ES 开发教程(19):绘制迷你太阳系 绘制了红太阳,蓝地球,白月亮。使用的是glColor4f 来指定颜色的. 这

引路蜂移动软件 6613

9.23华为OD机试真题 新系统 - 小菊的寻宝之旅 (Java/Py/C/C++/Js/Go)

9.23华为OD机试真题 新系统 - 小菊的寻宝之旅 (Java/Py/C/C++/Js/Go)

算法大师! 979

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

安卓进阶——OpenGL ES

本文系统介绍了OpenGL在2D和3D图形开发中的应用。2D部分重点阐述了OpenGL ES在Android平台的高性能优势、核心渲染管线(顶点处理、纹理映射、着色器编程)以及实现流程,包括GLSurfaceView配置和Renderer实现。3D部分深入讲解了坐标系转换、矩阵变换(MVP矩阵)、深度测试、光照模型等关键技术,并提供了3D场景渲染的实现框架。文章不仅覆盖了基础绘制方法,还介绍了纹理滤镜、粒子系统、帧缓冲等进阶技巧,为移动端图形开发提供了全面指导。通过系统学习这些内容,开发者可以实现...

Meteors.的博客 981

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: Android OpenGL ES详解——多重采样抗锯齿(MSAA)
下一篇: Android OpenGL ES详解——Renderer接口介绍
闲暇部落
博客等级 码龄12年 2775粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值