OpenGL织梦之旅【第三章】第4节.glut键盘鼠标响应

opengl学习篇之 画直线 圆 和矩形 // opengl画直线程序框架.cpp : 定义应用程序的入口点。 // //鼠标画线小程序 #include "stdafx.h" #include "opengl画直线程序框架.h" #include <glut.h> #include <math.h> #define N 1000 //maximum line numbers #define Pi... 阅读详情

        对于一个游戏来说,能够和玩家进行交互是很重要的。通过键盘、鼠标和手柄,游戏

程序接受玩家的各项指令,从而做出反应。在控制台程序中,我们可以使用kbhit()函数来判断玩家是否有输入,如果有,再调用getch函数就可以接受到玩家的输入信息。

        如:

if (kbhit() != 0)                                      //按下一个键
{
    c=getch();
	 ProcessInput(c);
}
else
{
	GameRun();
}

        glut也同样给我们提供了处理键盘鼠标事件的方法,是通过注册回调函数来实现的。

        下面就介绍一下这些函数。

1. void glutKeyboardFunc(void(*func)(unsigned char key,int x,int y));

        这个函数可以用来处理键盘上可以用ascii码表示的键按下的事件,key就是这个键ascii码,x和y则是键摁下时鼠标相对于窗口左上角的位置。

        具体用法:

        在main函数里,调用glutKeyboardFunc(&ProcessKeyboard),这样就注册了一个函数ProcessKeyboard。

        再完成函数体:

        

void ProcessKeyboard(unsigned char key,int x,int y)
{
		if (key == 'p')
		{
			SnapScreen(400,400,"data/screen.bmp");
		}
}

        这样,编译运行程序后,按下p键,就能够实时截图了!

2. void glutSpecialFunc(void (*func)(int key,int x,int y));

        这个函数是用来处理一些特殊键(如:F1,F2,etc)摁下的事件。参数key是这个键编号,在glut.h中预定义了这些常量:

        #define GLUT_KEY_F1          1

        #define GLUT_KEY_F2          2

        #define GLUT_KEY_F3          3...

        还有很多,大家可以自己打开glut.h找到自己需要的。

        同样,x和y也是当前鼠标的位置。

        具体实现:

        main函数里,glutSpecialFunc(&ProcessSpecialKeyboead);

void ProcessSpecialKeyboead(int key, int x, int y) 
{
	if (key == GLUT_KEY_F1)
	{
		SnapScreen(400,400,"data/screen.bmp");
	}
	if (key == GLUT_KEY_F2)
	{
		exit(0);
	}
}

        当摁下F1键,可以截图;摁下F2键,就会关闭程序。

3.  void glutMouseFunc(void(*func)(int button,int state,int x,int y));

        这个函数用来处理鼠标左右键和中键摁下的事件。

        其中button保存的是摁下的鼠标键的键位信息。

        在glut.h中,有定义:

                #define GLUT_LEFT_BUTTON     0

                #define GLUT_MIDDLE_BUTTON   1

                #define GLUT_RIGHT_BUTTON    2

        参数state表示这个事件发生是这个键是摁下还是松开。

                #define GLUT_DOWN         0

                #define GLUT_UP           1

        参数x和y则表示当前鼠标的位置。

        具体实现:

        main函数里,glutMouseFunc(&ProcessMouse);

void ProcessMouse(int button,int state,int x,int y)
{
		if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
		{
			SnapScreen(x,WinHeight-y,"data/screen.bmp");  
//把glut坐标转化成OpenGL内的坐标
//因为得到的x,y是相对于屏幕左上角的坐标,
//而SnapScreen函数内的glReadPixels函数处理的是按屏幕左下角为原点的//坐标系的坐标,所以这里需要转化一下。
		}
}

4.  void glutMotionFunc(void(*func)(int x,int y));

        这个函数是处理当鼠标键摁下时,鼠标拖动的事件。当鼠标拖动时,将每一帧都调用一次这个函数。

5.  void glutPassiveMotionFunc(void (*func)(int x,int y));

        这个函数是处理当没有鼠标键摁下时,鼠标拖动的事件。当鼠标拖动时,将每一帧都调用一次这个函数。同上面的差不多。

6.  void glutEntryFunc(void(*func)(int state));

        这个函数则是处理鼠标离开和进入窗口的事件。参数state的值在glut.h中有定义:

                #define GLUT_LEFT         0

                #define GLUT_ENTERED      1

        好,那么在介绍了这些函数后,大家应该可以使用glut来制作一些游戏了,如连连看,俄罗斯方块等。

附本节全部代码:

#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
#include <vector>
#include <iostream>
#define PI 3.1415926
#define BITMAP_ID 0x4D42
using std::vector;
int WinWidth,WinHeight;
int LoadBitmap(const char *file)
{
	unsigned int ID;      //纹理的id
	int width,height;   
	byte *image;          //接受图像数据
	FILE *fp;             //文件指针
	BITMAPFILEHEADER FileHeader;     //接受位图文件头
	BITMAPINFOHEADER InfoHeader;     //接受位图信息头
	
	fp=fopen(file,"rb");
	if (fp == NULL)
	{
		printf("Exception: Fail to open file!\n");
		return -1;
	}
	fread(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	if(FileHeader.bfType != BITMAP_ID)   //确保文件是一个位图文件,效验文件类型
	{ 
		printf("Exception: This file is not a bmp file!\n");
		fclose(fp);
		return -1;
	}
	fread(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	width=InfoHeader.biWidth; 
	height=InfoHeader.biHeight;
	InfoHeader.biSizeImage = width*height*3;
	fseek(fp, FileHeader.bfOffBits, SEEK_SET);  //将文件指针移动到实际图像数据处
	image=(byte *)malloc(sizeof(byte)*InfoHeader.biSizeImage); //申请空间
	if (image == NULL)
	{
		free(image);
		printf("Exception: No enough space!\n");
		return -1;
	}
	fread(image, 1, InfoHeader.biSizeImage, fp);
	fclose(fp);  

	glGenTextures(1, &ID);

    glBindTexture(GL_TEXTURE_2D, ID);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
   	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width,
	                  height, GL_BGR_EXT, GL_UNSIGNED_BYTE,
	                  image);
	return ID;  


}
vector<unsigned int> V_ID;          //用来保存生成的纹理id
int now,cnt;                        //now是当前所使用的纹理在vector中的下标
									//cnt是用来计时的变量

bool SnapScreen(int width,int height,const char *file)
{
	byte *image;          //接受图像数据
	FILE *fp;             //文件指针
	BITMAPFILEHEADER FileHeader;     //接受位图文件头
	BITMAPINFOHEADER InfoHeader;     //接受位图信息头

	FileHeader.bfType=BITMAP_ID;                                                  //ID设置为位图的id号
	FileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);       //实际图像数据的位置在文件头和信息头之后
	FileHeader.bfReserved1=0;                                                     //必须设置为0
	FileHeader.bfReserved2=0;                                                     //必须设置为0
	FileHeader.bfSize=height*width*24+FileHeader.bfOffBits;                       //BMP图像文件大小

	InfoHeader.biXPelsPerMeter = 0;                                               //水平分辨率,这里暂时设为0就是
	InfoHeader.biYPelsPerMeter = 0;                                               //垂直分辨率,这里暂时设为0就是
	InfoHeader.biClrUsed = 0;                                                     //图像使用的颜色,这里暂时设为0就是
	InfoHeader.biClrImportant = 0;                                                //重要的颜色数,这里暂时设为0就是                         //垂直分辨率,这里暂时设为0就是
	InfoHeader.biPlanes=1;														  //必须设置为1
	InfoHeader.biCompression=BI_RGB;                                              //设置为BI_RGB时,表示图像并没有彩色表
	InfoHeader.biBitCount=24;                                                     //图像的位数
	InfoHeader.biSize=sizeof(BITMAPINFOHEADER);                                   //结构体的大小
	InfoHeader.biHeight=height;                                                 
	InfoHeader.biWidth=width;                                                     
	InfoHeader.biSizeImage=height*width*4;                                        

	image=(byte *)malloc(sizeof(byte)*InfoHeader.biSizeImage);
	if (image == NULL)
	{
		free(image);
		printf("Exception: No enough space!\n");
		return false;
	}
	
	//像素格式设置4字节对齐
	glPixelStorei(GL_UNPACK_ALIGNMENT,4);
	//接收出像素的数据
	glReadPixels(0,0,width,height,GL_BGR_EXT,GL_UNSIGNED_BYTE,image);
	
	fp=fopen(file,"wb");
	if (fp == NULL)
	{
		printf("Exception: Fail to open file!\n");
		return false;
	}
	
	fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
	fwrite(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
	fwrite(image, InfoHeader.biSizeImage, 1, fp);
	free(image);
	fclose(fp);	
	return true;
}
void Draw()
{
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);   
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, V_ID[now]);
	glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	if (cnt <= 50)
		glColor4f(1.0,1.0,1.0,(float)cnt/50.0);
	else
		glColor4f(1.0,1.0,1.0,1.0-((float)cnt-50.0)/50.0);
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f);glVertex2f(-1,-1);
		glTexCoord2f(1.0f, 0.0f);glVertex2f(1,-1);
		glTexCoord2f(1.0f, 1.0f);glVertex2f(1,1);
		glTexCoord2f(0.0f, 1.0f);glVertex2f(-1,1);
	glEnd();
	glDisable(GL_TEXTURE_2D);  

	glutSwapBuffers();
}
void Update()
{
	cnt++;
	if (cnt >= 100)               //当cnt加到100的时候,换下一张图片
	{
		now++;
		now%=V_ID.size();         //保证now值的正确性
		cnt=0;                    //将cnt值置0,开始下一个图片的显示
	}
    glutPostRedisplay();
}
void Reshape(int w,int h)
{
	WinWidth=w;
	WinHeight=h;
    w=w>h?h:w;
    glViewport(0,0,(GLsizei)w,(GLsizei)w);
}
void init()
{
	int n,i;
	char str[100],file[100];
	V_ID.clear();                         //清空容器
	FILE *fp;
	fp=fopen("data/data.txt","r");
	fscanf(fp,"%d",&n);
	while (n--)
	{
		fscanf(fp,"%s",str);
		sprintf(file,"data/%s",str);      
		i=LoadBitmap(file);
		if (i == -1)                       //读取图片失败
			continue;
		else                                 
			V_ID.push_back(i);             //把图片的id放到V_ID的末尾保存起来
	}
	fclose(fp);
	now=0;
}
void ProcessKeyboard(unsigned char key,int x,int y)
{
	if (key == 'p')
	{
		SnapScreen(WinWidth,WinHeight,"data/screen.bmp");
	}
}
void ProcessSpecialKeyboead(int key, int x, int y) 
{
	if (key == GLUT_KEY_F1)
	{
		SnapScreen(WinWidth,WinHeight,"data/screen.bmp");
	}
	if (key == GLUT_KEY_F2)
	{
		exit(0);
	}
}
void ProcessMouse(int button,int state,int x,int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		SnapScreen(x,WinHeight-y,"data/screen.bmp");  //把glut坐标转化成OpenGL内的坐标
	}
}
int main(int argc, char *argv[])
{
	WinWidth=400;
	WinHeight=400;
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(WinWidth, WinHeight);
    glutCreateWindow("HelloOpenGL");
    glutReshapeFunc(&Reshape);
    glutIdleFunc(&Update);
    glutDisplayFunc(&Draw);

	glutKeyboardFunc(&ProcessKeyboard);
	glutSpecialFunc(&ProcessSpecialKeyboead);
	glutMouseFunc(&ProcessMouse);

	init();
    glutMainLoop();
    return 0;
}









glut实现连续按键处理 前面一篇文章我向大家介绍了我自己制作的基于glut的OpenGL框架。接下来我们要加入交互的内容,说到交互,其实就是键盘的控制了。我们会在这一次体会到面向对象机制给我们带来的巨大便利以及glut给我们带来的诸多方便。 组件化glut按键处理功能,这是一个好主意。在这个想法下,我将glut按键处理的功能写到一个类,叫作KeyEvent。下面是我们这个类的定义: 立即下载

相关推荐

MCNP 减方差技巧(最全)

MCNP的减方差技巧,核心在于不显著增加计算时间的前提下,通过修改模拟过程来降低结果的统计误差。尤其适用于,这类问题中粒子很难到达探测器区域,直接模拟效率极低栅元重要性是常用的减方差技巧,该方法主要对计算模型的不同区域定义不同的重要性数值。当粒子从重要性低的区域废物重要性高的区域,产生更多粒子,增大统计量;当从重要性高的区域进入重要性低的区域,会进行,增快计算效率。n= 中子,N;光子,P;电子 Exi= 栅元i的重要性I=栅元总数项目IMP卡是必须的,除非使用了WWN卡如果粒子进入0。

chencheng1127的博客 926

openGL中使用GLFW库键盘按键不响应

openGL系列文章目录 文章目录openGL系列文章目录前言一、openGL键盘事件不响应二、解决步骤1.glfw库事件响应回调函数错误原因运行结果源码下载 前言 Gouraud 着色也容易受到其他伪影影响。如果镜面高光整个范围都在模型中的一个三角 形内——即高光范围内一个模型顶点也没有——那么它可能不会被渲染出来。由于镜面反射 分量是依顶点计算的,因此,当模型所有顶点都没有镜面反射分量时,其光栅化后的像素 也不会有镜面反射光。 一、openGL键盘事件不响应 二、解决步骤 1.glfw库事件响应回调函数

aoxuestudy的专栏 1594

七步设计高频变压器

七步设计高频变压器

m0_71394959的博客 5401

PyOpenGL解决键盘事件无法响应 | Python

目录 描述 解决方法 描述 最近在完成《计算机图形学基础》3.4.2的作业,要求是使用键盘上的P键绘制线段。 书上写的是先写一个键盘输入注册函数(下面为错误代码) def pressKey(key: str, x: int, y: int) -> None: """ 监听键盘操作 :param key: 按下哪个按键 :param x: 光标横坐标 :param y: 光标纵坐标 :return: """ if key

RC Kanashii的博客 717

Part03 数据结构

本文介绍了CSP-S初赛中常见的高级数据结构及其实现,包括: 线性结构:双端栈、双端队列、单调队列、优先队列和ST表,重点分析了它们的特点、时间复杂度及典型应用场景。 集合与森林:并查集(带路径压缩和按秩合并)和树的孩子兄弟表示法,展示了多叉树转化为二叉树存储的方法。 特殊树结构:包括二叉堆、树状数组、线段树和字典树,详细说明了它们的构建、查询和更新操作,特别强调了线段树的递归实现和字典树的前缀匹配特性。 每种数据结构都配有核心C++代码实现,涉及数组模拟、动态规划和树形结构等编程技巧,适合算法竞赛选手快速

weixin_43863957的博客 1181

LaTeX伪代码字体大小调整全攻略:从algorithm到algorithm2e的实战技巧

本文详细介绍了在LaTeX中调整伪代码字体大小的全面技巧,涵盖algorithm、algorithmicx和algorithm2e等主流算法包的使用方法。从基础命令到高级配置,帮助用户解决学术论文和技术文档中的伪代码排版问题,提升算法展示的专业性和可读性。特别针对不同期刊格式要求,提供了实用的字体调整方案。

weixin_29297127的博客 437

实验3—OpenGL的键盘交互绘制

实验3 OpenGL的键盘交互绘制

weixin_52030647的博客 1423

15、分布式查询处理详解

本博文深入探讨了分布式环境下的查询处理与优化技术。从查询处理的基本概念出发,分析了在分布式系统中执行查询所面临的额外挑战,并通过实例比较了不同的执行策略。文章详细介绍了查询优化的组成要素,包括搜索空间、成本模型和搜索策略,同时涵盖了查询处理的多个层次以及数据本地化的核心方法。此外,还讨论了连接排序优化、分布式成本模型以及多种查询优化方法,如静态优化、动态优化和混合优化。最后,提出了自适应查询处理的概念,旨在提高分布式查询的灵活性和效率。通过综合应用这些技术,可以有效提升分布式数据库的查询性能,降低通信和计算

gan8painter的博客 73

Apache Kylin 命令注入漏洞复现(CVE-2020-1956)

Apache Kylin 中的静态 API 存在安全漏洞,可以将os命令与用户输入字符串连接起来,攻击者可以在Kylin没有任何保护或验证的情况下执行任何os命令。

0xSec 1558

OpenGL(十六) 鼠标、键盘交互响应事件

OpenGL中通过鼠标和键盘跟程序交互的实现需要实现注册鼠标和键盘响应事件,在一定条件下,该事件被触发,事件里的程序被执行,达到交互的目的。 通过glutMouseFunc(&OnMouse)注册鼠标事件,OnMouse是鼠标事件的响应,函数格式是void OnMouse(int button,int state,int x,int y); 通过glutKeyboardFunc

牧野的博客 4万+

Eplan设计师必会—伺服安全回路的设计方法

本文介绍了在EPLAN中设计伺服STO安全回路的方法。首先需查阅伺服驱动器说明书确定STO接线端子,重点关注双通道配置。设计步骤包括:使用黑盒子功能绘制驱动器外形,正确标注STO接线点,并连接安全继电器或PLC的安全输出。关键注意事项有:必须采用双通道独立布线,确保同步动作,遵循故障安全原则,使用常闭触点串联回路。文中以西门子V90和汇川伺服为例说明具体接线要求,并附有项目实例参考。

Qinmingyue13的博客 436

OpenGL织梦之旅【第一章】使用glut工具包配置OpenGL环境

第1章.使用glut工具包配置OpenGL环境       GLUT是一个方便实用的opengl工具包,它可以帮助你快捷地建立窗口,接受键盘鼠标响应,并且不受平台限制。对于我们初学者来说,使用这个包可以帮助我们很快地入门。当我们对程序有更高的需求时,我们再学习怎么样搭建基于windows应用程序的opengl程序框架。       下面以VC6.0为例,说明安装glut的步骤:

仰望圣光的plusplus7 1899

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

OpenGL---GLUT教程(五) GLUT键盘控制

  GLUT教程             键盘输入GLUT允许我们编写程序,在里面加入键盘输入控制,包括了普通键,和其他特殊键(如F1,UP)。在这一章里我们将学习如何去检测哪个键被按下,可以从GLUT里得到些什么信息,和如何处理键盘输入。 到现在,你应该注意到了,只要你想控制一个事件的处理,你就必须提前告诉GLUT,哪个函数将完成这个任务。到现在为止,我们已经使用GLUT告诉

xie_zi的专栏 3万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

OpenGL---GLUT教程(九) GLUT鼠标

           GLUT教程              鼠标在前几节,我们看了怎么使用GLUT的keyboard函数,来增加一个OpenGL程序的交互性。现在,是时候研究下鼠标了。GLUT的鼠标接口提供一些列的选项来增加鼠标的交互性。也就是检测鼠标单击,和鼠标移动。 检测鼠标Clicks和键盘处理一样,GLUT为你的注册函数(也就是处理鼠标clicks事件的函数)

xie_zi的专栏 1万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

OpenGL(二十) glutSpecialFunc响应键盘方向控制键

OpenGL的glut中使用glutMouseFunc函数注册鼠标响应事件,使用glutKeyboardFunc函数注册键盘响应事件,对键盘上特殊的4个方向按键的响应函数是glutSpecialFunc。 方向键响应事件的实现函数的格式是void SpecialKey(GLint key,GLint x,GLint y); 其中key对应4个方向按键,上下左右按键分别对应于GL

牧野的博客 1万+

OpenGL键盘事件处理

GLUT提供了两个函数用于设置键盘事件的回调函数,一个用于处理普通按键,一个处理特殊功能按键(如箭头、F1~F12)。 先看看处理普通按键的函数: void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y)); 回调函数func的第一个参数是按键的ASCII码,剩下的是按键时候的鼠标坐标。鼠标坐标是相对窗口的左上角

子宽的专栏 8830

opengl键值控制二

程序接受玩家的各项指令,从而做出反应。在控制台程序中,我们可以使用kbhit()函数来判断玩家是否有输入,如果有,再调用getch函数就可以接受到玩家的输入信息。 如: if (kbhit() != 0)                                      //按下一个键 {     c=getch();   ProcessInput(c); } else {

Andy20081251的专栏 1188

OpenGL学习例程精析(键盘和鼠标的调用)

void keyboard (unsigned char key, int x, int y) { switch (key) { case 's': case 'S': glBindTexture(GL_TEXTURE_2D, texName[0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 12, 44, subImageWidth, subImageHeight

KingsMan666的博客 537

GLUT教程

键盘输入             GLUT允许我们编写程序,在里面加入键盘输入控制,包括了普通键,和其他特殊键(如F1,UP)。在这一章里我们 将学习如何去检测哪个键被按下,可以从GLUT里得到些什么信息,和如何处理键盘输入。             到现在,你应该注意到了

2031

openGL 键盘,鼠标响应事件应用

openGl

Dream 9633

OpenGL的键盘交互绘制+(详细代码)

一、首先我们先调出实验一的源代码运行:// ConsoleApplication2.cpp: 定义控制台应用程序的入口点。 // //(生成一个初始矩形)————蓝矩白景 #include "stdafx.h" #include &lt;Windows.h&gt; #include &lt;gl\glut.h&gt; #include &lt;stdlib.h&gt; vo...

qq_40610760的博客 9475

【OpenGL】-009 GLUT中处理键盘鼠标事件

【OpenGL】-009 GLUT中处理键盘鼠标事件   键盘和鼠标是GUI程序获取用户输入的重要方式,在windows程序中,通过WM_KEY_DOWN/WM_KEY_UP/WM_LBUTTONDOWN/WM_RBUTTONDOWN等消息的响应,用户可以方便的处理键盘鼠标的输入。在使用GLUT作为窗口管理时,如何进行键盘和鼠标的输入处理呢? 文章目录【OpenGL】-009 GLUT中处理键盘鼠...

freehawkzk的专栏 2499
上一篇: POJ 2387 Til the Cows Come Home
下一篇: POJ 3007 Organize Your Train part II
plusplus7
博客等级 码龄15年 59粉丝 173原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值