bool CCxImage_GLView::LoadTexture(
const
char *tex_name,
const
char *alpha_name, unsigned
int &texID)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
// TODO: Add your command handler code here
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
CxImage image ,alpha,blendTex;
//
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
unsigned
char *pImage_RGBA = NULL;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
// Load the bitmap using the aux function stored in glaux.lib
//pImage = auxDIBImageLoad(tex_name);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.Load(tex_name);
// Make sure valid image data was given to pImage, otherwise return false
if(!image.IsValid())
return false;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
int sizeX,sizeY;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
sizeX = image.GetWidth();
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
sizeY = image.GetHeight();
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
float texAspectRatio = (
float)sizeX / (
float)sizeY;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if(alpha_name && strlen(alpha_name) > 0 )
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
int imageSize_RGB = sizeX * sizeY * 3;
int imageSize_RGBA = sizeX * sizeY * 4;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
alpha.Load(alpha_name);
if(!alpha.IsValid())
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
return false;
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
// allocate buffer for a RGBA image
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
pImage_RGBA =
new unsigned
char[imageSize_RGBA];
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
RGBQUAD col_image,col_alpha;
for(
int y=0;y<sizeY;y++)
for(
int x=0;x<sizeX;x++)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
col_image = image.GetPixelColor(x,y,
false);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
col_alpha = alpha.GetPixelColor(x,y,
false);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
pImage_RGBA[(x+y*sizeX)*4 +0] = col_image.rgbRed;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
pImage_RGBA[(x+y*sizeX)*4 +1] = col_image.rgbGreen;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
pImage_RGBA[(x+y*sizeX)*4 +2] = col_image.rgbBlue;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
pImage_RGBA[(x+y*sizeX)*4 +3] = col_alpha.rgbRed;
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glGenTextures(1, &texID);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glBindTexture(GL_TEXTURE_2D, texID);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Don't forget to use GL_RGBA for our new image data
we support Alpha transparency now!
// Build Mipmaps (builds different versions of the picture for distances - looks better)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX,
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA);
if(pImage_RGBA)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
delete [] pImage_RGBA;
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
else if(image.AlphaIsValid())
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
int imageSize_RGB = sizeX * sizeY * 3;
long imageSize_RGBA = sizeX * sizeY * 4;
// allocate buffer for a RGBA image
// pImage_RGBA = new unsigned char[imageSize_RGBA];
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.Encode2RGBA(pImage_RGBA,imageSize_RGBA);
// Generate a texture with the associative texture ID stored in the array
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glGenTextures(1, &texID);
// This sets the alignment requirements for the start of each pixel row in memory.
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
// Bind the texture to the texture arrays index and init the texture
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glBindTexture(GL_TEXTURE_2D, texID);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
//Assign the mip map levels and texture info
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Build Mipmaps (builds different versions of the picture for distances - looks better)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, sizeX,
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
sizeY, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.FreeMemory( pImage_RGBA);
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
else ![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
// Generate a texture with the associative texture ID stored in the array
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glGenTextures(1, &texID);
// This sets the alignment requirements for the start of each pixel row in memory.
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
// Bind the texture to the texture arrays index and init the texture
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glBindTexture(GL_TEXTURE_2D, texID);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
//Assign the mip map levels and texture info
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Build Mipmaps (builds different versions of the picture for distances - looks better)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, sizeX,
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
sizeY, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.GetBits());
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
//glEnable(GL_TEXTURE_2D);
// Now we need to free the image data that we loaded since openGL stored it as a texture
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
return true;
![ExpandedBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
}
void CCxImage_GLView::OnSaveScene()
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
{
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
// TODO: Add your command handler code here
static char BASED_CODE szFilter[] = "jpg Files (*.jpg)|*.jpg|bmp Files (*.bmp)|*.bmp|tga Files (*.tga)|*.tga|All Files (*.*)|*.*||";
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
CString filename;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
CString ext = "";
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if(filename.IsEmpty())
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
filename = "NoName";
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
CFileDialog dlg(
false, "jpg",filename, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if(dlg.DoModal() == IDOK)
![ExpandedSubBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
{
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
ext = dlg.GetFileExt();
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
filename = dlg.GetPathName();
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
//CDC* m_pDC; // Windows设备描述表
//HGLRC m_hRC; // OpenGL渲染描述表
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
// TODO: Add your command handler code here
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
wglMakeCurrent(m_pDC->m_hDC,m_hRC);
//这里要注意,如果就面渲染完毕的时候,调用了wglMakeCurrent(NULL,NULL);上面一行就一定要加上。
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
int expand = 0;
if((m_width *3)%4)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
expand = 4 - (m_width*3)%4;
//保证位图宽度能被4整除
int mapSize = (m_width*3 +expand) * (m_height);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if(mapSize == 0)
return;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
//hDIB = (HGLOBAL) ::GlobalAlloc(GHND,mapSize);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
unsigned
char * pTmp =
new BYTE[mapSize];
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
if(!pTmp)
return ;
// 读取屏幕像素
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
glReadPixels(0, 0, m_width, m_height, GL_BGR_EXT, GL_UNSIGNED_BYTE, pTmp);
// glPixelStorei(GL_PACK_ALIGNMENT, 1);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
// BMP信息头
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
CxImage image;
//image.CreateFromHBITMAP(hbit);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.CreateFromArray(pTmp,m_width,m_height,24,m_width*3 + expand,
false);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.SetJpegQuality(98);
//指定JPG文件的质量(0-100)
if(ext == "jpb")
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.Save(filename,CXIMAGE_FORMAT_JPG);
else if(ext == "bmp")
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.Save(filename,CXIMAGE_FORMAT_BMP);
else if(ext == "tga")
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
image.Save(filename,CXIMAGE_FORMAT_TGA);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
//pFile->Write(pTmp,mapSize*3);
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
delete[] pTmp;
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![ExpandedSubBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
}
![InBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![ExpandedBlockEnd.gif](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
}