OpenGL 可移动的桌子上可移动的茶壶瞄

例程1 可以当做练习,这是学长给的补充代码。可以根据提示写上去。


//This is example1.
// This assignment may cost you some efferts, so I give you some important HINTS, hope that may help you.
// Enjoy the coding and thinking, do pay more attention to the library functions used in OPENGL, such as how they are used? 
//what are the parameters used? and why?

// 实验报告里面多写点感想,即对函数的理解,以及调用的顺序,步骤等。思考为什么是这样子调用的,为什么参数是这样子设置的?。。。等等你觉得值得研究的问题。
#include <stdlib.h>
#include <GL/glut.h>
#include <stdbool.h>


float fTranslate;
float fRotate;
float fScale     = 1.0f;	// set inital scale value to 1.0f

bool bPersp = false;
bool bAnim = false;
bool bWire = false;

int wHeight = 0;
int wWidth = 0;

//todo
//hint: some additional parameters may needed here when you operate the teapot

void Draw_Leg()
{
	glScalef(1, 1, 3);
	glutSolidCube(1.0);
}

void Draw_Scene()
{
	glPushMatrix();
	glTranslatef(0, 0, 4+1);
	glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.
	//todo; hint: when operate the teapot, you may need to change some parameters
	glutSolidTeapot(1);
	glPopMatrix();
    //draw complete table.
	glPushMatrix();
	glTranslatef(0, 0, 3.5);
	glScalef(5, 4, 1);
	glutSolidCube(1.0);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(-1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();
	//completed
}

void updateView(int width, int height)
{
	glViewport(0,0,width,height);						// Reset The Current Viewport 

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	float whRatio = (GLfloat)width/(GLfloat)height;    //reset the ratio of width and height
	
	if (bPersp){																//bPersp is a parameter when  it equals 1 then select perspective else ortho
		gluPerspective(65.0, whRatio, 1.0,100.0);            // temporarily answer 
		//todo when 'p' operation, hint: use FUNCTION gluPerspective
	}
	else
	    glOrtho(-3 ,3, -3, 3,-100,100);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
}

void reshape(int width, int height)
{
	if (height==0)										// Prevent A Divide By Zero By
	{
		height=1;										// Making Height Equal One
	}

	wHeight = height;
	wWidth = width;

	updateView(wHeight, wWidth);
}
/*
void reshape (int width ,int height )
{
	if (height == 0)
		height = 1;

	glViewport(0.0, 0.0, width, height);   //default

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	
	if (bPersp){	
		gluPerspective(65.0,  (GLfloat)width/(GLfloat)height; , 1.0,100.0);  
	}
	else
	    glOrtho(-3 ,3, -3, 3,-100,100);

	glMatrixMode(GL_MODELVIEW);		//default
	glLoadIdentity(); //default 
}
*/

void idle()
{
	glutPostRedisplay();  //
}

float eye[] = {0, 0, 8};
float center[] = {0, 0, 0};
//todo; hint: you may need another ARRAY when you operate the teapot

void key(unsigned char k, int x, int y)
{
	switch(k)
	{
	case 27:
	case 'q': {exit(0); break; }
	case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; }

	case ' ': {bAnim = !bAnim; break;}
	case 'o': {bWire = !bWire; break;}

	case 'a': {//todo, hint: eye[] and center[] are the keys to solve the problems
		break;
			  }
	case 'd': {//todo
		break;
			  }
	case 'w': {//todo
		break;
			  }
	case 's': {//todo
		break;
			  }
	case 'z': {//todo
		break;
			  }
	case 'c': {//todo
		break;
			  }

  //茶壶相关操作
	case 'l': {//todo, hint:use the ARRAY that you defined, and notice the teapot can NOT be moved out the range of the table.
		break;
			  }
	case 'j': {//todo
		break;
			  }
	case 'i': {//todo
		break;
			  }
	case 'k': {//todo
		break;
			  }
	case 'e': {//todo
		break;
			  }
	}
}


void redraw()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									// Reset The Current Modelview Matrix

	gluLookAt(eye[0], eye[1], eye[2],
		center[0], center[1], center[2],
		0, 1, 0);				// 场景(0,0,0)的视点中心 (0,5,50),Y轴向上

	if (bWire) {
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	}
	else {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
    GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_pos[] = {5,5,5,1};

	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, white);
	glEnable(GL_LIGHT0);

//	glTranslatef(0.0f, 0.0f,-6.0f);			// Place the triangle at Center
	glRotatef(fRotate, 0, 1.0f, 0);			// Rotate around Y axis
	glRotatef(-90, 1, 0, 0);
	glScalef(0.2, 0.2, 0.2);
	Draw_Scene();						// Draw Scene

	if (bAnim) fRotate    += 0.5f;

	//todo; hint: when you want to rotate the teapot, you may like to add another line here =)
	glutSwapBuffers();
}

int main (int argc,  char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(480,480);
	glutWindowPosition(100,100);
	glutCreateWindow("Simple GLUT App");

	glutDisplayFunc(redraw);
	glutReshapeFunc(reshape);	
	glutKeyboardFunc(key);
	glutIdleFunc(idle);

	glutMainLoop();
	return 0;
}

//This is my program!
#include <stdlib.h>
#include <GL/glut.h>
#include <stdbool.h>


float fTranslate;
float fRotate;
float fScale = 1.0f;	// set inital scale value to 1.0f

bool bPersp = false;
bool bAnim = false;
bool bWire = false;

int wHeight = 0;
int wWidth = 0;

float fMovex = 0.0;
float fMovez = 0.0;
float fRotatet;
bool bTea = false;


void Draw_Leg()
{
	glScalef(1, 1, 3);
	glutSolidCube(1.0);
}

void Draw_Scene()
{
	glPushMatrix();
	//glTranslatef(0, 0, 5.0);
	glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.
	glTranslatef(0+fMovex,5.0,0+fMovez);
	glRotatef(fRotatet, 0, 1.0f, 0);	

	//todo; hint: when operate the teapot, you may need to change some parameters
	glutSolidTeapot(1);
	glPopMatrix();


   	//draw complete table.
	glPushMatrix();
	glTranslatef(0, 0, 3.5);
	glScalef(5, 4, 1);
	glutSolidCube(1.0);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(-1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();
	//completed
}

void updateView(int width, int height)
{
	glViewport(0,0,width,height);						// Reset The Current Viewport 

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	float whRatio = (GLfloat)width/(GLfloat)height;    //reset the ratio of width and height
	
	if (bPersp){					   //bPersp is a parameter when  it equals 1 then select perspective else ortho
		gluPerspective(25.0, whRatio, 1.0,200.0);            // temporarily answer 
		//todo when 'p' operation, hint: use FUNCTION gluPerspective
	}
	else
	    glOrtho(-3 ,3, -3, 3,-100,100);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
}

void reshape(int width, int height)
{
	if (height==0)										// Prevent A Divide By Zero By
	{
		height=1;										// Making Height Equal One
	}

	wHeight = height;
	wWidth = width;

	updateView(wHeight, wWidth);
}
/*
void reshape (int width ,int height )
{
	if (height == 0)
		height = 1;

	glViewport(0.0, 0.0, width, height);   //default

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	
	if (bPersp){	
		gluPerspective(65.0,  (GLfloat)width/(GLfloat)height; , 1.0,100.0);  
	}
	else
	    glOrtho(-3 ,3, -3, 3,-100,100);

	glMatrixMode(GL_MODELVIEW);		//default
	glLoadIdentity(); //default 
}
*/

void idle()
{
	glutPostRedisplay();  //glutPostRedisplay marks the current window as needing to be redisplayed.
}

float eye[] = {0, 0, 8};
float center[] = {0, 0, 0};
/*float array[16][20]={0};
for(int i=0;i<=16;i++)
	for(int j=0;j<=40;j+=2){
		array[i][j]=-2.5+0.25*(j/2);
		array[i][++j]=2-0.25*i;
	}*/

void keyboard(unsigned char k, int x, int y)
{
	switch(k)
	{
	case 27:
	case 'q': {exit(0); break; }
	case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; }

	case ' ': {bAnim = !bAnim; break;}
	case 'o': {bWire = !bWire; break;}

	case 'a': {eye[0]=eye[0]+0.2;center[0]=center[0]+0.2;break; }
	case 'd': {eye[0]=eye[0]-0.2;center[0]=center[0]-0.2;break; }
	case 'w': {eye[1]=eye[1]-0.2;center[1]=center[1]-0.2;break; }
	case 's': {eye[1]=eye[1]+0.2;center[1]=center[1]+0.2;break; }

	case 'z': {eye[2]=eye[2]-0.2;break; }
	case 'c': {eye[2]=eye[2]+0.2;break; }

  //茶壶相关操作
	case 'l': {
		if(fMovex!=2.0) 
			fMovex+=0.25;
		break;
			  }
	case 'j': {
		if(fMovex!=-2.0) 
			fMovex-=0.25;
		break;
			  }
	case 'i': {
		if(fMovez!=-2.0) 
			fMovez-=0.25;
		break;
			  }
	case 'k': {
		if(fMovez!=2.0) 
			fMovez+=0.25;
		break;
			  }
	case 'e': {bTea=!bTea;//todo
		break;
			  }
	}
}


void display()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									// Reset The Current Modelview Matrix

	gluLookAt(eye[0], eye[1], eye[2],
		center[0], center[1], center[2],
		0, 1, 0);				// 场景(0,0,0)的视点中心 (0,5,50),Y轴向上  eye [] ={0, 0, 8}

	if (bWire) {
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	}
	else {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}

	glEnable(GL_DEPTH_TEST);
	// light
	glEnable(GL_LIGHTING);
   	GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_pos[] = {5,5,5,1};

	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, white);
	glEnable(GL_LIGHT0);

//	glTranslatef(0.0f, 0.0f,-6.0f);			// Place the triangle at Center
	glRotatef(fRotate, 0, 1.0f, 0);			// Rotate around Y axis
	glRotatef(-90, 1, 0, 0);
	glScalef(0.2, 0.2, 0.2);
	Draw_Scene();						// Draw Scene

	if (bAnim) fRotate    += 0.5f;
	if(bTea)   fRotatet  += 0.5f;
	
	glutSwapBuffers();
}

int main (int argc,  char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(480,480);
	glutInitWindowPosition(100,100);
	glutCreateWindow("Simple GLUT App");

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);	
	glutKeyboardFunc(keyboard);
	glutIdleFunc(idle);  //not be familiar  to the  function 

	glutMainLoop();
	return 0;
}





// my classmate's
#include <stdlib.h>
#include <stdio.h>
#include "glut.h"


float fTranslate_x;
float fTranslate_y;
float fRotate;
float fRotate_tea;
float xCoordinate_tea = 0;
float zCoordinate_tea = 5;
float fScale     = 1.0f;	// set inital scale value to 1.0f

bool bPersp = false;
bool bAnim = false;
bool bWire = false;

int wHeight = 0;
int wWidth = 0;

//todo
//hint: some additional parameters may needed here when you operate the teapot

void Draw_Leg()
{
	glScalef(1, 1, 3);
	glutSolidCube(1.0);
}

void Draw_Scene()
{
	glPushMatrix();
	glTranslatef(xCoordinate_tea,0, zCoordinate_tea);
	glRotatef(fRotate_tea, 0, 0, 1.0f);			// Rotate around Y axis
	glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.
	//todo; hint: when operate the teapot, you may need to change some parameters
	glutSolidTeapot(1);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(0, 0, 3.5);
	glScalef(5, 4, 1);
	glutSolidCube(1.0);
	glPopMatrix();

	glPushMatrix();
	glTranslatef(1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();

	glPushMatrix();
	glTranslatef(-1.5, 1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(-1.5, -1, 1.5);
	Draw_Leg();
	glPopMatrix();

}

void updateView(int width, int height)
{
	glViewport(0,0,width,height);						// Reset The Current Viewport

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	float whRatio = (GLfloat)width/(GLfloat)height;
	
	if (bPersp){
		//todo when 'p' operation, hint: use FUNCTION gluPerspective
		gluPerspective(45.0f,(GLfloat)(width+5)/(GLfloat)height,0.1f,100.0f);
		printf("sds\n");
	}
	else
	    glOrtho(-3 ,3, -3, 3,-100,100);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
}

void reshape(int width, int height)
{
	if (height==0)										// Prevent A Divide By Zero By
	{
		height=1;										// Making Height Equal One
	}

	wHeight = height;
	wWidth = width;

	updateView(wHeight, wWidth);
}

void idle()
{
	glutPostRedisplay();
}

float eye[] = {0,0, 8};
float center[] = {0, 0, 0};
//todo; hint: you may need another ARRAY when you operate the teapot

void key(unsigned char k, int x, int y)
{
	switch(k)
	{
	case 27:
	case 'q': {exit(0); break; }
	case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; }

	case ' ': {bAnim = !bAnim; break;}
	case 'o': {bWire = !bWire; break;}

	case 'a': {//todo, hint: eye[] and center[] are the keys to solve the problems
		fTranslate_x -= 0.1f;
		break;
			  }
	case 'd': {//todo
		fTranslate_x += 0.1f;
		break;
			  }
	case 'w': {//todo
		fTranslate_y += 0.1f;
		break;
			  }
	case 's': {//todo
		fTranslate_y -= 0.1f;
		break;
			  }
	case 'z': {//todo
		eye[0] +=1;
		break;
			  }
    case 'x': {//todo
		eye[1] +=1;
		break;
			  }
	case 'c': {//todo
		eye[2] +=1;
		break;
			  }

    case 'v': {//todo
		eye[0] -=1;
		break;
			  }
    case 'b': {//todo
		eye[1] -=1;
		break;
			  }
	case 'n': {//todo
		eye[2] -=1;
		break;
			  }




  //茶壶相关操作
	case 'l': {//todo, hint:use the ARRAY that you defined, and notice the teapot can NOT be moved out the range of the table.
		if(xCoordinate_tea<=2.0f)
			xCoordinate_tea += 0.1f;
		break;
			  }
	case 'j': {//todo
		if(xCoordinate_tea>=-2.0f)
			xCoordinate_tea -= 0.1f;
		break;
			  }
	case 'i': {//todo
		zCoordinate_tea += 0.1f;
		break;
			  }
	case 'k': {//todo
		if(zCoordinate_tea>=5)
			zCoordinate_tea -= 0.1f;
		break;
			  }
	case 'e': {//todo
	    fRotate_tea    += 3.0f;
		break;
			  }
	}
}


void redraw()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									// Reset The Current Modelview Matrix

	gluLookAt(eye[0], eye[1], eye[2],
		center[0], center[1], center[2],
		0, 1, 0);				// 场景(0,0,0)的视点中心 (0,5,50),Y轴向上

	if (bWire) {
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	}
	else {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
    GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat light_pos[] = {5,5,5,1};

	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, white);
	glEnable(GL_LIGHT0);

	glTranslatef(fTranslate_x, fTranslate_y,0);			// Place the triangle at Center
	glRotatef(fRotate, 0, 1.0f, 0);			// Rotate around Y axis
	glRotatef(-90, 1, 0, 0);
	glScalef(0.2, 0.2, 0.2);
	Draw_Scene();						// Draw Scene

	if (bAnim) fRotate    += 0.5f;

	//todo; hint: when you want to rotate the teapot, you may like to add another line here =)
	glutSwapBuffers();
}

int main (int argc,  char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(480,480);
	int windowHandle = glutCreateWindow("Simple GLUT App");

	glutDisplayFunc(redraw);
	glutReshapeFunc(reshape);	
	glutKeyboardFunc(key);
	glutIdleFunc(idle);

	glutMainLoop();
	return 0;
}

1)我有点看不太懂程序,所以我把该程序分解开来。在前面的draw_scene中,teapot的画法为什么先平移到了Z轴,然后一个旋转90度绕X轴,画了一个teapot(1.0)。

通过对teapot的绘制函数进行变化,

1.  glPushMatrix();  

2.  glTranslatef(0, 0, 4+1);  

3.  glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.  

4.  //todo; hint: when operate the teapot, you may need to change some parameters  

5.  glutSolidTeapot(1);  

6.  glPopMatrix();  

 

a.当我将2、3行注释掉的时候,那么也就是说,teapot的绘制将在默认的坐标系中,但是出现了下图:


b.在上面的注释情况下,我把glTranslatef(5.0,0.0,0.0),如下图:

 

C 那么在这个时候,考虑到了y的坐标系,为了证明想法,还是实践了一下:于是我将上述的参数改为. glTranslatef(0.0,50.0,0.0)。由于正交投影没有显示出变化,但在透视投影下我看到了:


D 那么之后的参数验证也可想而知了。但是为什么teapot的默认坐标系不是右手坐标系呢?teapot的默认坐标系:x指向了右方,y指向了屏幕里面,z指向了上方。

找了一个关于teapot的OpenGL例程。

1.  #include <GL/glut.h>  

2.  void init();  

3.  void display();  

4.  int main(int argc, char* argv[])  

5.  {  

6.      glutInit(&argc, argv);  

7.      glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);  

8.      glutInitWindowPosition(0, 0);  

9.      glutInitWindowSize(300, 300);  

10.     glutCreateWindow("OpenGL 3D View");  

11.     init();  

12.     glutDisplayFunc(display);  

13.     glutMainLoop();  

14.     return 0;  

15. }  

16.   

17. void init()  

18. {  

19.     glClearColor(0.0, 0.0, 0.0, 0.0);  

20.     glMatrixMode(GL_PROJECTION);  

21.     glOrtho(-5, 5, -5, 5, 5, 15);  

22.     glMatrixMode(GL_MODELVIEW);  

23.     gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);  

24. }  

25.   

26. void display()  

27. {  

28.     glClear(GL_COLOR_BUFFER_BIT);  

29.     glColor3f(1.0, 0, 0);  

30.     glutWireTeapot(3);  

31.     glFlush();  

32.   

33. }

但是这个显示的teapot是正常的默认的坐标系,一个可漂亮的茶壶了。

最后的最后我找到了问题的根源了:是在display里面有个无端的旋转函数。。真是晕倒!!!

2)reshape 回调函数分为了俩个部分。是为了之后的调用。但是这样我觉得还不如写成后一种。这样在需要的时候直接调用reshape函数。显得比较简洁。

1.  void updateView(int width, int height)  

2.  {  

3.      glViewport(0,0,width,height);                       // Reset The Current Viewport  

4.    

5.      glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix  

6.      glLoadIdentity();                                   // Reset The Projection Matrix  

7.    

8.      float whRatio = (GLfloat)width/(GLfloat)height;  

9.        

10.     if (bPersp){  

11.         //todo when 'p' operation, hint: use FUNCTION gluPerspective  

12.     }  

13.     else  

14.         glOrtho(-3 ,3, -3, 3,-100,100);  

15.   

16.     glMatrixMode(GL_MODELVIEW);                         // Select The Modelview Matrix  

17. }  

18.   

19. void reshape(int width, int height)  

20. {  

21.     if (height==0)                                      // Prevent A Divide By Zero By  

22.     {  

23.         height=1;                                       // Making Height Equal One  

24.     }  

25.   

26.     wHeight = height;  

27.     wWidth = width;  

28.   

29.     updateView(wHeight, wWidth);  

30. }  



这儿懒的再写一次了,不能上传Word文档。。。喵喵


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值