OpenGL学习三十七:Windows 3D字体
(此节内容对应NEHE教程第14课)
本节主要说明OpenGL结合WINDOW 创建并使用3D字体
3D图形字体。创建过程和2D基本相似
1.声明显示列表base = glGenLists(256);
2.创建新的FONT font = CreateFont(WinAPI)
3.选择我们需要的字体 oldfont = (HFONT)SelectObject(hDC, font);(WinAPI)
4.创建显示列表 wglUseFontOutlines();这里和2D的使用方式不同,3D的使用这个函数
按照ASII码进行存储。显示时候也是按照此逻辑进行寻找,如A对应65 则在显示列表65进行寻找
5.设置显示列表基础值 glListBase(base - n)
6.使用显示列表进行文字绘制 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
GLYPHMETRICSFLOAT | 用来保存轮廓字体显示列表中对应的每一个列表的位置和方向的信息(每个显示列表中文字的详细信息) | ||||
wglUseFontOutlines(HDC, DWORD, DWORD, DWORD, FLOAT,FLOAT, int, GLYPHMETRICSFLOAT) | 创建并填充显示列表 | ||||
HDC | Windows的设备描述表 | ||||
DWORD | 显示列表字体的第一个字符的ASCII值 | ||||
DWORD | 字符数 | ||||
DWORD | 第一个显示列表的名称 | ||||
FLOAT | 体的光滑度,越小越光滑,0.0为最光滑的状态 | ||||
FLOAT | 在z方向突出的距离 | ||||
int |
使用多边形或者线性来生成字符 WGL_FONT_LINES WGL_FONT_POLYGONS |
||||
GLYPHMETRICSFLOAT | 每个显示列表中文字的详细信息 |
#include "header.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 ApplicationGLuint base; // Base Display List For The Font Set
GLfloat rot; // Used To Rotate The Textbool 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 DefaultGLYPHMETRICSFLOAT gmf[256]; // Storage For Information About Our Outline Font CharactersLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProcGLvoid BuildFont(GLvoid) // Build Our Bitmap Font
{HFONT font; // Windows Font IDbase = glGenLists(256); // Storage For 256 Charactersfont = CreateFont( -12, // Height Of Font0, // Width Of Font0, // Angle Of Escapement0, // Orientation AngleFW_BOLD, // Font WeightFALSE, // ItalicFALSE, // UnderlineFALSE, // StrikeoutANSI_CHARSET, // Character Set IdentifierOUT_TT_PRECIS, // Output PrecisionCLIP_DEFAULT_PRECIS, // Clipping PrecisionANTIALIASED_QUALITY, // Output QualityFF_DONTCARE|DEFAULT_PITCH, // Family And Pitch"Comic Sans MS"); // Font NameSelectObject(hDC, font); // Selects The Font We CreatedwglUseFontOutlines( hDC, // Select The Current DC0, // Starting Character255, // Number Of Display Lists To Buildbase, // Starting Display Lists0.0f, // Deviation From The True Outlines0.2f, // Font Thickness In The Z DirectionWGL_FONT_POLYGONS, // Use Polygons, Not Linesgmf); // Address Of Buffer To Recieve Data
}GLvoid KillFont(GLvoid) // Delete The Font
{glDeleteLists(base, 256); // Delete All 256 Characters
}GLvoid glPrint(const char *fmt, ...) // Custom GL "Print" Routine
{float length=0; // Used To Find The Length Of The Textchar text[256]; // Holds Our Stringva_list ap; // Pointer To List Of Argumentsif (fmt == NULL) // If There's No Textreturn; // Do Nothingva_start(ap, fmt); // Parses The String For Variablesvsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbersva_end(ap); // Results Are Stored In Textfor (unsigned int loop=0;loop<(strlen(text));loop++) // Loop To Find Text Length{length+=gmf[text[loop]].gmfCellIncX; // Increase Length By Each Characters Width}glTranslatef(-length/2,0.0f,0.0f); // Center Our Text On The ScreenglPushAttrib(GL_LIST_BIT); // Pushes The Display List BitsglListBase(base); // Sets The Base Character to 0glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List TextglPopAttrib(); // Pops The Display List Bits
}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
{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 CalculationsglEnable(GL_LIGHT0); // Enable Default Light (Quick And Dirty)glEnable(GL_LIGHTING); // Enable LightingglEnable(GL_COLOR_MATERIAL); // Enable Coloring Of MaterialBuildFont(); // Build The Fontreturn 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 Screen And Depth BufferglLoadIdentity(); // Reset The Current Modelview MatrixglTranslatef(0.0f,0.0f,-10.0f); // Move One Unit Into The ScreenglRotatef(rot,1.0f,0.0f,0.0f); // Rotate On The X AxisglRotatef(rot*1.5f,0.0f,1.0f,0.0f); // Rotate On The Y AxisglRotatef(rot*1.4f,0.0f,0.0f,1.0f); // Rotate On The Z Axis// Pulsing Colors Based On The RotationglColor3f(1.0f*float(cos(rot/20.0f)),1.0f*float(sin(rot/25.0f)),1.0f-0.5f*float(cos(rot/17.0f)));glPrint("NeHe - %3.2f",rot/50); // Print GL Text To The Screenrot+=0.5f; // Increase The Rotation Variablereturn TRUE; // Everything Went OK
}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}KillFont();
}/* 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 Outline Font 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 Outline Font Tutorial",640,480,16,fullscreen)){return 0; // Quit If Window Was Not Created}}}}// ShutdownKillGLWindow(); // Kill The Windowreturn (msg.wParam); // Exit The Program
}
OpenGL学习三十七:Windows 3D字体相关推荐
- 计算机图形学——OpenGL学习系列之绘制3D下的小桌子
计算机图形学--OpenGL学习系列之绘制3D下的小桌子 做的一个小练习,主要用到了几何变换还有gl自带的一个绘制立方体的函数,顺便体会一下glPush和glPop的用法.另外,从2D到3D,开心到飞 ...
- OpenGL学习笔记3 —— 绘制3D物体、鼠标交互、反向变换
/* reference http://nehe.gamedev.net/article/using_gluunproject/16013/ */#include <windows.h> ...
- Java多线程学习三十七:volatile 的作用是什么?与 synchronized 有什么异同
volatile 是什么 首先我们就来介绍一下 volatile,它是 Java 中的一个关键字,是一种同步机制.当某个变量是共享变量,且这个变量是被 volatile 修饰的,那么在修改了这个变量的 ...
- OpenGL学习三十九:飘动的旗帜
(此节内容对应NEHE教程第11课) 目前为止我们做的例子都是平面的,这个例子是带有波动效果的, 2维图形包括X,Y两个坐标系.因此看到的是平面的. 3维图形由X,Y,Z三个坐标系构成,当Z坐标不为0 ...
- torch学习 (三十七):DCGAN详解
文章目录 引入 1 生成器 2 鉴别器 3 模型训练:生成器与鉴别器的交互 4 参数设置 5 数据载入 6 完整代码 7 部分输出图像示意 7.1 真实图像 7.2 训练200个批次 7.2 训练40 ...
- NeHe OpenGL教程 第三十七课:卡通映射
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- OpenGL入门学习[三]
OpenGL入门学习[三] http://xiaxveliang.blog.163.com/blog/static/2970803420126246501930/ OpenGL入门学习[十一] 我们在 ...
- 【OpenGL学习笔记⑥】——3D变换【旋转的正方体 实现地月系统 旋转+平移+缩放】
✈️ 文章目录 零. 成果预览图 一.3D立方体的顶点数组 二.纹理旋转 三.纹理缩放 四.画n个3D图形 五.轨道的数学公式 六.深度缓冲(Z 缓冲) 七.完整代码 八.参考附录: 神器的正方体 ☁ ...
- windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互
windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互 前面两篇学习笔记分别介绍了IRP和IO_STACK_LOCATION,整个设备栈来处理这个IRP,但是每个设 ...
- 【我的OpenGL学习进阶之旅】关于3D模型知识之:什么是obj文件和mtl文件
文章目录 一.学习3D模型的背景 二.3D模型效果展示 三.好奇3D模型文件是啥内容? 3.1 打开.obj文件 3.2 打开.obj文件 3.3 在外部使用查看3D模型的软件打开.obj文件 3.3 ...
最新文章
- 例题6-4 破损的键盘(又名:悲剧文本)(Broken Keyboard(a.k.a. Beiju Text), UVa 11988)
- linux只剩 目录挂载,linux(centOS7)的基本操作(五) 磁盘、分区、挂载、卸载
- NodeJS开发c++扩展模块
- java-linux-eclipse配置
- java 集合迭代器_Java中的集合迭代器
- HIVE高级函数--get_json_object()和json_tuple()
- 部署应用程序到Tomcat的webapps目录
- 决策树(五)--OpenCV决策树
- Photoshop2021入门教程|认识Photoshop界面
- 一个人、一场梦、一座空城、一生心疼
- java微信多客服_怎么实现微信多公众号管理?有哪些多客服系统?
- 子之错父之过什么意思_子不教父之过?
- 基于WFP的windows驱动对TCP数据的抓取,修改以及注意事项
- RT-Thread学习1-tcp_modbus
- [万字长文]使用 React 重写学成在线前端项目 I 代码完整可运行,步骤有详解
- oracle rac mpp,DB2 purescale vs Oracle RAC
- Intel VMD技术和SPDK VMD驱动模块介绍及使用
- 在一家虚拟现实公司工作是什么感受?
- 计算机网络协议——OSI、TCP数据、IP数据包、Ethernet 数据包
- 悬镜安全 | 第五期 全球一周安全情报(0820-0826)
热门文章
- 两个有趣的统计学问题
- SQL统计次月复购率
- Doris 5 处理 Sentinel-1 时 prepare_datastack.py 代码报错 ValueError: cannot reshape array of size * into
- 使用transform使定位元素居中
- 建瓯市天气预报软件测试,南平天气(福建省南平市建瓯市天气预报)
- js中对new Date() 中转换字符串方法toLocaleString的使用
- WPF 动画:同为控件不同命
- 访问virtualbox虚拟机中架设的网站
- 18_数组的定义和访问
- layui.open使用例子播放m3u8视频