计算机图形学实验四真实感图形的绘制

真实感图形的绘制


一、实验目的

理解消隐的概念、原理;掌握几种常用的消隐算法的思想;能够编程实现经典的面消隐算法,如Z-buffer算法、画家算法等,以加深对消隐算法的理解和掌握。理解计算机图形学中有关着色、光照、材质、纹理处理的编程原理;加深学生对几何变换、投影变换以及观察变换的理解,并提高学生利用图形软件包绘制图形的能力;能够综合运用本课程所学的有关知识,编写具有一定真实感效果的三维物体程序。

二、实验要求

1.理解OpenGL中消隐的实现。
2.理解深度缓存和帧缓存的作用。
3.理解光源的设置、光照函数的含义。
4.增加纹理处理。

1.遮挡

#include<GL/glut.h>

enum{FILL,WIRE};
enum{SPHERE=1,CONE,WALLS};
int rendermode = FILL;
GLUquadricObj* sphere, * cone, * base;

static GLfloat lightpos[] = { 50.f,50.f,-320.f,1.f };
static GLfloat wall_mat[] = { 0.8f,0.8f,0.8f,1.f };
static GLfloat sphere_mat[] = { 1.0f,0.2f,0.2f,1.f };
static GLfloat cone_mat[] = { 0.2f,1.0f,0.2f,1.f };

void Initial();
void Display();
void menu(int );
void drawscene();

int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);

	glutInitWindowPosition(100, 100);
	glutInitWindowSize(500, 500);
	glutCreateWindow("遮挡");
	glutDisplayFunc(Display);

	glutCreateMenu(menu);
	glutAddMenuEntry("Solid Fill", FILL);//把FILL这个位置的参数传入到menu函数中
	glutAddMenuEntry("Wireframe", WIRE);
	glutAttachMenu(GLUT_RIGHT_BUTTON);//按右键显示菜单


	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}
void Initial() {
	glMatrixMode(GL_PROJECTION);
	glFrustum(-100.0, 100.0, -100.0, 100.0, 320.0, 640.0);//透视显示:左右下上近远
	glMatrixMode(GL_MODELVIEW);

	glEnable(GL_DEPTH_TEST);//打开深度缓冲设置
	glDepthFunc(GL_LEQUAL);//判断遮挡关系时,离视点近的遮挡离视点远的物体。GL-NEVER不判断,GL_ALWAYS,GL_LESS,GL_LEQUAL
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

	glNewList(SPHERE, GL_COMPILE);
	sphere = gluNewQuadric();//创建一个对象
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
	gluSphere(sphere, 50.f, 40, 40);//让该对象画球,参数:球体,半径,经度分割线,纬度分割线
	gluDeleteQuadric(sphere);//释放对象
	glEndList();

	glNewList(CONE, GL_COMPILE);
	cone = gluNewQuadric();
	base = gluNewQuadric();
	glPushMatrix();
	glRotatef(-90.f, 1.f, 0.f, 0.f);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
	gluQuadricOrientation(base, GLU_INSIDE);
	gluDisk(base, 0., 40., 20, 1);//碟盘(圆锥的底,如果画圆柱需要两个底)参数:对象,内环半径,外环半径,分割线,同心圆线
	gluCylinder(cone, 40., 0., 120., 20, 20);//圆锥,参数:对象,下半径,上半径,高,经度分割线,纬度分割线
	glPopMatrix();
	gluDeleteQuadric(cone);
	gluDeleteQuadric(base);
	glEndList();

	//WALLS
	glNewList(WALLS,GL_COMPILE);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);

	glBegin(GL_QUADS);
	glNormal3f(0.f, 1.f, 0.f);
	glVertex3f(-100.f, -100.f, -320.f);
	glVertex3f(100.f, -100.f, -320.f);
	glVertex3f(100.f, -100.f, -520.f);
	glVertex3f(-100.f, -100.f, -520.f);

	//left wall
	glNormal3f(1.f, 0.f, 0.f);
	glVertex3f(-100.f, -100.f, -320.f);
	glVertex3f(-100.f, -100.f, -520.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glVertex3f(-100.f, 100.f, -320.f);
	//right wall
	glNormal3f(-1.f, 0.f, 0.f);
	glVertex3f(100.f, -100.f, -320.f);
	glVertex3f(100.f, 100.f, -320.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(100.f, -100.f, -520.f);
	//ceiling
	glNormal3f(0.f, -1.f, 0.f);
	glVertex3f(-100.f, 100.f, -320.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(100.f, 100.f, -320.f);
	//back wall
	glNormal3f(0.f, 0.f, 1.f);
	glVertex3f(-100.f, -100.f, -520.f);
	glVertex3f(100.f, -100.f, -520.f);
	glVertex3f(100.f, 100.f, -520.f);
	glVertex3f(-100.f, 100.f, -520.f);
	glEnd();
	glEndList();
}

void menu(int selection) {
	rendermode = selection;
	glutPostRedisplay();
}

void drawscene() {
	glCallList(WALLS);
	glPushMatrix();
	glTranslatef(-20.f, -40.f, -400.f);
	glCallList(SPHERE);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(40.f, -100.f, -420.f);
	glCallList(CONE);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-40.f, -40.f, -400.f);
	glCallList(CONE);
	glPopMatrix();
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	switch (rendermode)
	{
	case FILL:
		drawscene(); break;
	case WIRE:
		glDisable(GL_LIGHTING);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//GL_POINTS,GL_FILL
		glColor4f(0.0, 0.0, 0.0, 1.0);
		drawscene();
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		glEnable(GL_LIGHTING);
		break;

	default:
		break;
	}
	glFlush();
}


2.光源

(1)运行下列程序,理解光源的设置、光照函数的含义以及参数的含义。
(2)添加一个其他颜色的光源,使用“w、s、a、d”键控制光源的移动,体会多光源的效果,如图1所示。
在这里插入图片描述

#include<GL/glut.h>
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
static GLfloat xRot1 = 0.0f;
static GLfloat yRot1 = 0.0f;

void Initial() {
	GLfloat light_diffuse[] = { 1.0,1.0,1.0,1.0 };
	GLfloat light_ambient[] = { 0.0,0.5,0.5,1.0 };
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);//设置环境光颜色

	GLfloat light1_diffuse[] = { 1.0,1.0,1.0,1.0 };
	GLfloat light1_ambient[] = { 0.0,0.5,0.5,1.0 };
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); 
	glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);//设置环境光颜色

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);//启动光源LIGHT0
	glEnable(GL_LIGHT1);//启动光源LIGHT1
	glEnable(GL_DEPTH_TEST);//深度测试
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void ChangeSize(int w, int h)
{
	if (h == 0) h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(40.0f, (GLfloat)w / (GLfloat)h, 1.0f, 20.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	GLfloat light0_position[] = { 0.0f,0.0f,1.5f,1.0f };//最后一个参数1.0指前面设置的点位置,0.0为无限远处
	GLfloat light1_position[] = { 0.0f,0.0f,1.5f,1.0f };

	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);
	glRotated(yRot, 0.0f, 1.0f, 0.0f);
	glRotated(xRot, 1.0f, 0.0f, 0.0f);
	//设置光源的位置
	glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
	glTranslatef(0.0f, 0.0f, 1.5f);
	//绘制一个黄色的光球
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 1.0f, 0.0f);
	glutSolidSphere(0.1f, 50.0f, 50.0f);
	glEnable(GL_LIGHTING);

	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);
	glRotated(yRot1, 0.0f, 1.0f, 0.0f);
	glRotated(xRot1, 1.0f, 0.0f, 0.0f);
	//设置光源的位置
	glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
	glTranslatef(0.0f, 0.0f, 1.5f);
	//绘制一个红色的光球
	glDisable(GL_LIGHTING);
	glColor3f(1.0f, 0.0f, 0.0f);
	glutSolidSphere(0.1f, 50.0f, 50.0f);
	glEnable(GL_LIGHTING);

	glLoadIdentity();
	//设置材质属性
	GLfloat mat_diffuse[] = { 0.0f,0.5f,1.0f,1.0f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
	glTranslatef(0.0f, 0.0f, -5.0f);

	glutSolidTorus(0.275, 0.85, 50, 50);
	glLoadIdentity();

	glutSwapBuffers();
}

void Keys(unsigned char key, int x, int y) {
	switch (key)
	{
	case 'i':xRot -= 5.0f; break;
	case 'k':xRot += 5.0f; break;
	case 'j':yRot -= 5.0f; break;
	case 'l':yRot += 5.0f; break;

	case 'w':xRot1 -= 5.0f; break;
	case 's':xRot1 += 5.0f; break;
	case 'a':yRot1 -= 5.0f; break;
	case 'd':yRot1 += 5.0f; break;
	default:
		break;
	}

	if (key > 356.0f)
		xRot = 0.0f;
	if (key < -1.0f)
		xRot = 355.0f;
	if (key > 356.0f)
		yRot = 0.0f;
	if (key < -1.0f)
		yRot = 355.0f;

	if (key > 356.0f)
		xRot1 = 0.0f;
	if (key < -1.0f)
		xRot1 = 355.0f;
	if (key > 356.0f)
		yRot1 = 0.0f;
	if (key < -1.0f)
		yRot1 = 355.0f;

	glutPostRedisplay();
}

int main(int argc, char* argv[])
{
	//初始化工具包
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	//窗口设置
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("光源");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(Display);
	glutKeyboardFunc(Keys);

	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}



3.彩虹

使用一维纹理映射,绘制一段七色彩虹,如图2所示。
在这里插入图片描述

#include<GL/glut.h>
#include <math.h>
#ifndef M_pI
#define M_PI 3.141592649
#endif

static GLubyte roygbiv_image[8][3] = {
	{0x3f,0x00,0x3f},//深蓝紫色
	{0x7f,0x00,0x7f},//蓝紫色
	{0xbf,0x00,0xbf},//靛蓝
	{0x00,0x00,0xff},//蓝色
	{0x00,0xff,0x00},//绿色
	{0xff,0xff,0x00},//黄色
	{0xff,0x7f,0x00},//橙色
	{0xff,0x00,0x00},//红色
};

void ChangeSize(int width, int height) {
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (float)width / (float)height, 0.1, 1000.0);
	glMatrixMode(GL_MODELVIEW);
}

void Initial() {
	glClearColor(0.3, 0.8, 1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//最基本的执行纹理映射的步骤
	//1.定义纹理,2.控制纹理,3.说明纹理映射的方式,4.绘制场景
	//1.定义纹理
	glTexImage1D(GL_TEXTURE_1D, 0, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, roygbiv_image);
	//2.控制纹理,设定纹理如何对应屏幕像素,实现纹理缩放纹理重复
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//3.说明纹理映射方式
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	//表示使用最靠近使用纹理像素的四个纹素的加权平均值
	//定义一维纹理,颜色分量为RGB
	//宽度为8,边界为0,使用无符号整数
	//定义纹理环境参数,使用纹理图像
}

void Display() {
	GLfloat x, y, z, th;
	//draw ground
	glDisable(GL_TEXTURE_1D);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	glPushMatrix();
	glRotatef(10.0f, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.0, -40.0, -100.0);

	glColor3f(0.0, 0.8, 0.0);
	glBegin(GL_POLYGON);
	for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
		x = cos(th) * 200.0;
		z = sin(th) * 200.0;
		glVertex3f(x, 0.0, z);
	}
	glEnd();

	//draw rainbow
	glEnable(GL_TEXTURE_1D);
	glBegin(GL_QUAD_STRIP);//共享四边形
	for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
		x = cos(th) * 50.0;
		y = sin(th) * 50.0;
		z = -50.0;
		glTexCoord1f(0.0);
		glVertex3f(x, y, z);

		x = cos(th) * 55.0;
		y = sin(th) * 55.0;
		z = -50.0;
		glTexCoord1f(1.0);
		glVertex3f(x, y, z);
	}
	glEnd();
	glPopMatrix();
	glFlush();
}

int main(int argc, char *argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(792, 753);
	glutCreateWindow("彩虹");
	//调用绘图函数,回调函数,不断监听
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(Display);

	Initial();//必要的其他初始化函数
	glutMainLoop();//进入循环
	return 0;
}

4.纹理

使用图片纹理绘制不同花纹的茶壶,如图3所示。
在这里插入图片描述

链接: 图片在线转bmp格式.
将bmp格式文件放在工程目录中
在这里插入图片描述

#include <stdio.h>
#include <windows.h>
#include <GL/glut.h>
//读纹理函数:
#define BITMAP_ID 0x4D42
#define TEX_NUM 4
GLuint Texture[TEX_NUM];
char *TextureName[] = {
	"teapot1.BMP",
	"teapot2.BMP",
	"teapot3.BMP",
	"teapot4.BMP",
};
// 读纹理函数
// 纹理标示符数组,保存两个纹理的标示符
// 描述: 通过指针,返回filename 指定的bitmap文件中数据。
// 同时也返回bitmap信息头.(不支持-bit位图)
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
	FILE *filePtr;						// 文件指针
	BITMAPFILEHEADER bitmapFileHeader;	// bitmap文件头
	unsigned char	*bitmapImage;		// bitmap图像数据
	int	imageIdx = 0;					// 图像位置索引
	unsigned char tempRGB;				// 交换变量

	// 以“二进制+读”模式打开文件filename

	filePtr = fopen(filename,"rb");
	if (filePtr == NULL) return NULL;
	// 读入bitmap文件图
	fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
	// 验证是否为bitmap文件
	if (bitmapFileHeader.bfType != BITMAP_ID) {
		fprintf(stderr, "Error in LoadBitmapFile: the file is not a bitmap file\n");
		return NULL;
	}

	// 读入bitmap信息头
	fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
	// 将文件指针移至bitmap数据
	fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
	// 为装载图像数据创建足够的内存
	bitmapImage = new unsigned char[bitmapInfoHeader->biSizeImage];
	// 验证内存是否创建成功
	if (!bitmapImage) {
		fprintf(stderr, "Error in LoadBitmapFile: memory error\n");
		return NULL;
	}

	// 读入bitmap图像数据
	fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);
	// 确认读入成功
	if (bitmapImage == NULL) {
		fprintf(stderr, "Error in LoadBitmapFile: memory error\n");
		return NULL;
	}

	//由于bitmap中保存的格式是BGR,下面交换R和B的值,得到RGB格式
	for (imageIdx = 0; imageIdx < (bitmapInfoHeader->biSizeImage); imageIdx += 3) {
		tempRGB = bitmapImage[imageIdx];
		bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
		bitmapImage[imageIdx + 2] = tempRGB;
	}
	// 关闭bitmap图像文件
	fclose(filePtr);
	return bitmapImage;
}

//加载纹理的函数:
void texload(int i, char *filename)
{

	BITMAPINFOHEADER bitmapInfoHeader;			// bitmap信息头
	unsigned char*   bitmapData;				// 纹理数据

	bitmapData = LoadBitmapFile(filename, &bitmapInfoHeader);
	glBindTexture(GL_TEXTURE_2D, Texture[i]);

	// 指定当前纹理的放大/缩小过滤方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexImage2D(GL_TEXTURE_2D,
		0,		//mipmap层次(通常为,表示最上层)
		GL_RGB,	//我们希望该纹理有红、绿、蓝数据
		bitmapInfoHeader.biWidth,	//纹理宽带,必须是n,若有边框+2
		bitmapInfoHeader.biHeight,	//纹理高度,必须是n,若有边框+2
		0,		//边框(0=无边框, 1=有边框)
		GL_RGB,	//bitmap数据的格式
		GL_UNSIGNED_BYTE,	//每个颜色数据的类型
		bitmapData);		//bitmap数据指针
}

//绘制茶壶
GLint GenTeapotList()
{

	GLint lid = glGenLists(1);
	glNewList(lid, GL_COMPILE);

	GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat mat_diffuse[] = { 0.55, 0.55, 0.55, 1.0 };
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat mat_shininess[] = { 90.0 };
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

	glutSolidTeapot(0.5);
	glEndList();
	return lid;
}

//定义纹理的函数:
void init(void) //
{
	glEnable(GL_DEPTH_TEST);//打开深度测试

	//定义光源
	GLfloat position1[] = { 1.0, 1.0, 1.0, 0.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, position1);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	//定义纹理
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(TEX_NUM, Texture);
	for (int i = 0; i < TEX_NUM; i++) {
		texload(i, TextureName[i]);
		glBindTexture(GL_TEXTURE_2D, Texture[i]);

		//设置像素存储模式控制所读取的图像数据的行对齐方式.
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	}

	glDisable(GL_TEXTURE_2D);

}

void display(void)
{
	glClearColor(0.85f, 0.85f, 0.85f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, Texture[0]); //选择纹理图案
	glCallList(GenTeapotList());
	glFlush();
}

void reshape(GLsizei w, GLsizei h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);										//初始化工具包
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);	//设置显示模式
	glutInitWindowPosition(0, 0);								//设置窗口在屏幕上的位置
	glutInitWindowSize(500, 500);								//设置窗口的大小
	glutCreateWindow("纹理");						//打开屏幕窗口


	glutReshapeFunc(reshape);
	glutDisplayFunc(display);	//调用绘图函数
	init();						//必要的其他初始化函数
	glutMainLoop();				//进入循环

	return 0;
}
  • 8
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值