SOIL库加载纹理

2024-02-29 04:30
文章标签 加载 纹理 soil

本文主要是介绍SOIL库加载纹理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

NeHe教程里第六课使用glaux来加载纹理位图,但是glaux 库已经弃用。新的NeHe第六课教程中推荐了SOIL库。(下载,可以在这里获取能直接使用的文件)

SOIL库是一个小型的C语言库,用来加载纹理到OpenGL。它基于stb_image 1.16。
详情:http://www.lonesock.net/soil.html
我们使用时只需要简单的把SOIL.h SOIL.lib添加到工程就可以了。

bmp文件的使用:
在InitGL()中调用LoadGlTextures()函数:

int LoadGLTextures()                                    // Load Bitmaps And Convert To Textures  
{  /* load an image file directly as a new OpenGL texture */  texture[0] = SOIL_load_OGL_texture  (  "Data/NeHe.bmp",  SOIL_LOAD_AUTO,  SOIL_CREATE_NEW_ID,  SOIL_FLAG_INVERT_Y  );  if(texture[0] == 0)  return false;  // Typical Texture Generation Using Data From The Bitmap  glBindTexture(GL_TEXTURE_2D, texture[0]);  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);  return true;                                        // Return Success  
}  

unsigned int SOIL_load_OGL_texture(
const char *filename,
int force_channels,
unsigned int reuse_texture_ID,
unsigned int flags);
第一个参数为文件名;
第二个说明符,SOIL_LOAD_AUTO表示使用我们磁盘载入的;
第三个表示让SOIL为我们创建一个ID;
第四个参数SOIL_FLAG_INVERT_Y允许我们做是翻转Y轴
返回值,0表示失败,其他表示OpenGL上下文句柄

效果:
这里写图片描述

实例:
这里写图片描述

/**      This Code Was Created By Jeff Molofee 2000*      A HUGE Thanks To Fredric Echols For Cleaning Up*      And Optimizing The Base Code, Making It More Flexible!*      If You've Found This Code Useful, Please Let Me Know.*      Visit My Site At nehe.gamedev.net*/#include <windows.h>        // Header File For Windows
#include <stdio.h>          // Header File For Standard Input/Output
#include <gl\gl.h>          // Header File For The OpenGL32 Library
#include <gl\glu.h>         // Header File For The GLu32 Library#include "SOIL.h"HDC         hDC=NULL;       // Private GDI Device Context
HGLRC       hRC=NULL;       // Permanent Rendering Context
HWND        hWnd=NULL;      // Holds Our Window Handle
HINSTANCE   hInstance;      // Holds The Instance Of The Applicationbool    keys[256];          // Array Used For The Keyboard Routine
bool    active=TRUE;        // Window Active Flag Set To TRUE By Default
bool    fullscreen=TRUE;    // Fullscreen Flag Set To Fullscreen Mode By DefaultGLfloat xrot;               // X Rotation ( NEW )
GLfloat yrot;               // Y Rotation ( NEW )
GLfloat zrot;               // Z Rotation ( NEW )GLuint  texture[1];         // Storage For One Texture ( NEW )LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   // Declaration For WndProcint LoadGLTextures()                                    // Load Bitmaps And Convert To Textures
{/* load an image file directly as a new OpenGL texture */texture[0] = SOIL_load_OGL_texture("Data/NeHe.bmp",SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_INVERT_Y);if(texture[0] == 0)return false;// Typical Texture Generation Using Data From The BitmapglBindTexture(GL_TEXTURE_2D, texture[0]);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);return true;                                        // Return Success
}GLvoid ReSizeGLScene(GLsizei width, GLsizei height)     // Resize And Initialize The GL Window
{if (height==0)                                      // Prevent A Divide By Zero By{height=1;                                       // Making Height Equal One}glViewport(0,0,width,height);                       // Reset The Current ViewportglMatrixMode(GL_PROJECTION);                        // Select The Projection MatrixglLoadIdentity();                                   // Reset The Projection Matrix// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);                         // Select The Modelview MatrixglLoadIdentity();                                   // Reset The Modelview Matrix
}int InitGL(GLvoid)                                      // All Setup For OpenGL Goes Here
{if (!LoadGLTextures())                              // Jump To Texture Loading Routine ( NEW ){return FALSE;                                   // If Texture Didn't Load Return FALSE}glEnable(GL_TEXTURE_2D);                            // Enable Texture Mapping ( NEW )glShadeModel(GL_SMOOTH);                            // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f);               // Black BackgroundglClearDepth(1.0f);                                 // Depth Buffer SetupglEnable(GL_DEPTH_TEST);                            // Enables Depth TestingglDepthFunc(GL_LEQUAL);                             // The Type Of Depth Testing To DoglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really Nice Perspective Calculationsreturn TRUE;                                        // Initialization Went OK
}int DrawGLScene(GLvoid)                                 // Here's Where We Do All The Drawing
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth BufferglLoadIdentity();                                   // Reset The ViewglTranslatef(0.0f,0.0f,-5.0f);glRotatef(xrot,1.0f,0.0f,0.0f);glRotatef(yrot,0.0f,1.0f,0.0f);glRotatef(zrot,0.0f,0.0f,1.0f);glBindTexture(GL_TEXTURE_2D, texture[0]);glBegin(GL_QUADS);// Front FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);// Back FaceglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);// Top FaceglTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);// Bottom FaceglTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);// Right faceglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);// Left FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);glEnd();xrot+=0.3f;yrot+=0.2f;zrot+=0.4f;return TRUE;                                        // Keep Going
}GLvoid KillGLWindow(GLvoid)                             // Properly Kill The Window
{if (fullscreen)                                     // Are We In Fullscreen Mode?{ChangeDisplaySettings(NULL,0);                  // If So Switch Back To The DesktopShowCursor(TRUE);                               // Show Mouse Pointer}if (hRC)                                            // Do We Have A Rendering Context?{if (!wglMakeCurrent(NULL,NULL))                 // Are We Able To Release The DC And RC Contexts?{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC))                     // Are We Able To Delete The RC?{MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}hRC=NULL;                                       // Set RC To NULL}if (hDC && !ReleaseDC(hWnd,hDC))                    // Are We Able To Release The DC{MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hDC=NULL;                                       // Set DC To NULL}if (hWnd && !DestroyWindow(hWnd))                   // Are We Able To Destroy The Window?{MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hWnd=NULL;                                      // Set hWnd To NULL}if (!UnregisterClass("OpenGL",hInstance))           // Are We Able To Unregister Class{MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hInstance=NULL;                                 // Set hInstance To NULL}
}/*  This Code Creates Our OpenGL Window.  Parameters Are:                   **  title           - Title To Appear At The Top Of The Window              **  width           - Width Of The GL Window Or Fullscreen Mode             **  height          - Height Of The GL Window Or Fullscreen Mode            **  bits            - Number Of Bits To Use For Color (8/16/24/32)          **  fullscreenflag  - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)   */BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{GLuint      PixelFormat;            // Holds The Results After Searching For A MatchWNDCLASS    wc;                     // Windows Class StructureDWORD       dwExStyle;              // Window Extended StyleDWORD       dwStyle;                // Window StyleRECT        WindowRect;             // Grabs Rectangle Upper Left / Lower Right ValuesWindowRect.left=(long)0;            // Set Left Value To 0WindowRect.right=(long)width;       // Set Right Value To Requested WidthWindowRect.top=(long)0;             // Set Top Value To 0WindowRect.bottom=(long)height;     // Set Bottom Value To Requested Heightfullscreen=fullscreenflag;          // Set The Global Fullscreen FlaghInstance           = GetModuleHandle(NULL);                // Grab An Instance For Our Windowwc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redraw On Size, And Own DC For Window.wc.lpfnWndProc      = (WNDPROC) WndProc;                    // WndProc Handles Messageswc.cbClsExtra       = 0;                                    // No Extra Window Datawc.cbWndExtra       = 0;                                    // No Extra Window Datawc.hInstance        = hInstance;                            // Set The Instancewc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);          // Load The Default Iconwc.hCursor          = LoadCursor(NULL, IDC_ARROW);          // Load The Arrow Pointerwc.hbrBackground    = NULL;                                 // No Background Required For GLwc.lpszMenuName     = NULL;                                 // We Don't Want A Menuwc.lpszClassName    = "OpenGL";                             // Set The Class Nameif (!RegisterClass(&wc))                                    // Attempt To Register The Window Class{MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                                           // Return FALSE}if (fullscreen)                                             // Attempt Fullscreen Mode?{DEVMODE dmScreenSettings;                               // Device Modememset(&dmScreenSettings,0,sizeof(dmScreenSettings));   // Makes Sure Memory's CleareddmScreenSettings.dmSize=sizeof(dmScreenSettings);       // Size Of The Devmode StructuredmScreenSettings.dmPelsWidth    = width;                // Selected Screen WidthdmScreenSettings.dmPelsHeight   = height;               // Selected Screen HeightdmScreenSettings.dmBitsPerPel   = bits;                 // Selected Bits Per PixeldmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL){// If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){fullscreen=FALSE;       // Windowed Mode Selected.  Fullscreen = FALSE}else{// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);return FALSE;                                   // Return FALSE}}}if (fullscreen)                                             // Are We Still In Fullscreen Mode?{dwExStyle=WS_EX_APPWINDOW;                              // Window Extended StyledwStyle=WS_POPUP;                                       // Windows StyleShowCursor(FALSE);                                      // Hide Mouse Pointer}else{dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;           // Window Extended StyledwStyle=WS_OVERLAPPEDWINDOW;                            // Windows Style}AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);     // Adjust Window To True Requested Size// Create The Windowif (!(hWnd=CreateWindowEx(  dwExStyle,                          // Extended Style For The Window"OpenGL",                           // Class Nametitle,                              // Window TitledwStyle |                           // Defined Window StyleWS_CLIPSIBLINGS |                   // Required Window StyleWS_CLIPCHILDREN,                    // Required Window Style0, 0,                               // Window PositionWindowRect.right-WindowRect.left,   // Calculate Window WidthWindowRect.bottom-WindowRect.top,   // Calculate Window HeightNULL,                               // No Parent WindowNULL,                               // No MenuhInstance,                          // InstanceNULL)))                             // Dont Pass Anything To WM_CREATE{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}static  PIXELFORMATDESCRIPTOR pfd=              // pfd Tells Windows How We Want Things To Be{sizeof(PIXELFORMATDESCRIPTOR),              // Size Of This Pixel Format Descriptor1,                                          // Version NumberPFD_DRAW_TO_WINDOW |                        // Format Must Support WindowPFD_SUPPORT_OPENGL |                        // Format Must Support OpenGLPFD_DOUBLEBUFFER,                           // Must Support Double BufferingPFD_TYPE_RGBA,                              // Request An RGBA Formatbits,                                       // Select Our Color Depth0, 0, 0, 0, 0, 0,                           // Color Bits Ignored0,                                          // No Alpha Buffer0,                                          // Shift Bit Ignored0,                                          // No Accumulation Buffer0, 0, 0, 0,                                 // Accumulation Bits Ignored16,                                         // 16Bit Z-Buffer (Depth Buffer)  0,                                          // No Stencil Buffer0,                                          // No Auxiliary BufferPFD_MAIN_PLANE,                             // Main Drawing Layer0,                                          // Reserved0, 0, 0                                     // Layer Masks Ignored};if (!(hDC=GetDC(hWnd)))                         // Did We Get A Device Context?{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}if(!SetPixelFormat(hDC,PixelFormat,&pfd))       // Are We Able To Set The Pixel Format?{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}if (!(hRC=wglCreateContext(hDC)))               // Are We Able To Get A Rendering Context?{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}if(!wglMakeCurrent(hDC,hRC))                    // Try To Activate The Rendering Context{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}ShowWindow(hWnd,SW_SHOW);                       // Show The WindowSetForegroundWindow(hWnd);                      // Slightly Higher PrioritySetFocus(hWnd);                                 // Sets Keyboard Focus To The WindowReSizeGLScene(width, height);                   // Set Up Our Perspective GL Screenif (!InitGL())                                  // Initialize Our Newly Created GL Window{KillGLWindow();                             // Reset The DisplayMessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;                               // Return FALSE}return TRUE;                                    // Success
}LRESULT CALLBACK WndProc(   HWND    hWnd,           // Handle For This WindowUINT    uMsg,           // Message For This WindowWPARAM  wParam,         // Additional Message InformationLPARAM  lParam)         // Additional Message Information
{switch (uMsg)                                   // Check For Windows Messages{case WM_ACTIVATE:                           // Watch For Window Activate Message{if (!HIWORD(wParam))                    // Check Minimization State{active=TRUE;                        // Program Is Active}else{active=FALSE;                       // Program Is No Longer Active}return 0;                               // Return To The Message Loop}case WM_SYSCOMMAND:                         // Intercept System Commands{switch (wParam)                         // Check System Calls{case SC_SCREENSAVE:                 // Screensaver Trying To Start?case SC_MONITORPOWER:               // Monitor Trying To Enter Powersave?return 0;                           // Prevent From Happening}break;                                  // Exit}case WM_CLOSE:                              // Did We Receive A Close Message?{PostQuitMessage(0);                     // Send A Quit Messagereturn 0;                               // Jump Back}case WM_KEYDOWN:                            // Is A Key Being Held Down?{keys[wParam] = TRUE;                    // If So, Mark It As TRUEreturn 0;                               // Jump Back}case WM_KEYUP:                              // Has A Key Been Released?{keys[wParam] = FALSE;                   // If So, Mark It As FALSEreturn 0;                               // Jump Back}case WM_SIZE:                               // Resize The OpenGL Window{ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Heightreturn 0;                               // Jump Back}}// Pass All Unhandled Messages To DefWindowProcreturn DefWindowProc(hWnd,uMsg,wParam,lParam);
}int WINAPI WinMain( HINSTANCE   hInstance,          // InstanceHINSTANCE   hPrevInstance,      // Previous InstanceLPSTR       lpCmdLine,          // Command Line Parametersint         nCmdShow)           // Window Show State
{MSG     msg;                                    // Windows Message StructureBOOL    done=FALSE;                             // Bool Variable To Exit Loop// Ask The User Which Screen Mode They Preferif (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen=FALSE;                           // Windowed Mode}// Create Our OpenGL Windowif (!CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)){return 0;                                   // Quit If Window Was Not Created}while(!done)                                    // Loop That Runs While done=FALSE{if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))   // Is There A Message Waiting?{if (msg.message==WM_QUIT)               // Have We Received A Quit Message?{done=TRUE;                          // If So done=TRUE}else                                    // If Not, Deal With Window Messages{TranslateMessage(&msg);             // Translate The MessageDispatchMessage(&msg);              // Dispatch The Message}}else                                        // If There Are No Messages{// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()if ((active && !DrawGLScene()) || keys[VK_ESCAPE])  // Active?  Was There A Quit Received?{done=TRUE;                          // ESC or DrawGLScene Signalled A Quit}else                                    // Not Time To Quit, Update Screen{SwapBuffers(hDC);                   // Swap Buffers (Double Buffering)}if (keys[VK_F1])                        // Is F1 Being Pressed?{keys[VK_F1]=FALSE;                  // If So Make Key FALSEKillGLWindow();                     // Kill Our Current Windowfullscreen=!fullscreen;             // Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow("NeHe's Texture Mapping Tutorial",640,480,16,fullscreen)){return 0;                       // Quit If Window Was Not Created}}}}// ShutdownKillGLWindow();                                 // Kill The Windowreturn (msg.wParam);                            // Exit The Program
}

这篇关于SOIL库加载纹理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/757577

相关文章

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

使用WebP解决网站加载速度问题,这些细节你需要了解

说到网页的图片格式,大家最常想到的可能是JPEG、PNG,毕竟这些老牌格式陪伴我们这么多年。然而,近几年,有一个格式悄悄崭露头角,那就是WebP。很多人可能听说过,但到底它好在哪?你的网站或者项目是不是也应该用WebP呢?别着急,今天咱们就来好好聊聊WebP这个图片格式的前世今生,以及它值不值得你花时间去用。 为什么会有WebP? 你有没有遇到过这样的情况?网页加载特别慢,尤其是那

opengl纹理操作

我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是只显示几个多边形那样单调了。——但是这还不够。虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求。例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的。OpenGL纹理映射功能支持将

gazebo 已加载模型但无法显示

目录 写在前面的话问题一:robot_state_publisher 发布机器人信息失败报错一 Error: Error document empty.报错二 .xcaro 文件中有多行注释成功启动 问题二:通过 ros2 启动 gazebo 失败成功启动 问题三:gazebo 崩溃和无法显示模型问题四: 缺少 robot_description 等话题正确的输出 写在前面的话

JVM类的加载器及加载过程

类的加载器及加载过程 文章目录 类的加载器及加载过程类的加载过程加载:链接(验证、准备、解析):初始化: 类加载器的分类引导类加载器:BootstrapClassLoader 启动类加载器( C/C++实现,嵌套在JVM内部)自定义类加载器(所有派生于抽象类ClassLoader的类加载器)获取ClassLoader的途径 双亲委派机制(重点)判断两个Class对象是否为同一个类

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

Eclipse发布Maven项目到tomcat,无法加载到lib文件夹下的jar包

BMS 解决方法: 当我们发布web项目到tomcat时,访问地址时会报一个classnotfound的错误,但是eclipse中的项目中都已经添加了相应的类,有一种比较容易犯的错误是,你没有把额外所需的jar包加到tomcat中的lib文件夹中,在这里介绍一种在项目中直接添加jar包到lib目录下:  右键已创建的web项目——properties属性——点击Deployment Assem