当前位置: 首页 > 编程日记 > 正文

WhyGL:一套学习OpenGL的框架,及翻写Nehe的OpenGL教程

      最近在重学OpenGL,之所以说重学是因为上次接触OpenGL还是在学校里,工作之后就一直在搞D3D,一转眼已经毕业6年了.OpenGL这门手艺早就完全荒废了,现在只能是重学.学习程序最有效的办法是动手写,光看书是不行了,因为看书的时候很容易陷入对人类两大难题的思考中,以至于进展缓慢.这两大难题是:这特妈是啥?那特妈又是啥?在重学的过程中,我翻写了Nehe所有的OpenGL教程DEMO.本来打算把"翻写"写成"重构"的,但想想"重构"这个词这么高端大气上档次,通常只有牛B的人和装B的人爱提,我要是用"重构",感觉后者的嫌疑更大.

      先贴出我的OpenGL作品:

软件说明:

"WhyGL演示程序平台.exe"和"WhyGL.exe"都可以运行程序,不同之处在于,一个是基本的Windows窗体程序,一个是MFC的单文档界面程序.

主UI界面上,鼠标点击可以选择要运行的DEMO
键盘的上下键也可以选择DEMO,PageUp和PageDown用于翻页,回车键用于启动选中的DEMO

F11键用于全屏切换,
ESC用于退出当前DEMO及退出全屏
每个DEMO都会将提示文字信息显示在界面上,H键可以隐藏文字.

 

软件下载地址:
http://files.cnblogs.com/WhyEngine/WhyGL.7z


      所有的DEMO都写在同一个程序中,采用面向对象的方法,每一个DEMO都对应一个对象.Nehe的DEMO中基本上是采用全局变量,全局函数来实现,而我翻写的程序尽量将其封装为对象的成员变量和成员函数.之所以称这套系统为一个框架,是因为我提供了一套学习OpenGL的平台,可以帮助3D程序的初学者更容易入门,用户可以方便的在上面添加自己的程序.

      3D程序一开始接触会觉得很难,不过究其根本可以分为以下几个过程:

(1)初始化渲染设备;
(2)创建渲染数据,设置渲染状态;
(3)执行数据的处理操作;
(4)响应消息事件;
(5)渲染处理;
(6)删除渲染数据,恢复渲染状态;
(7)销毁渲染设备.

      在WhyGL框架中,我尽量将一些系列通用的复杂的流程封装好,以便于用户写代码时,只关心具体的渲染逻辑.这有些类似GLUT,在GLUT中将windows窗体的创建,事件处理都封装好,用户只填写回调函数即可实现.在WhyGL,为用户提供一个DEMO基类,用户需要继承该类,并添加自己的成员变量,重载其方法就可以绘制自己的图形.这就如同考试时将问答题改成填空题,降低了难度.

先提供个具体的DEMO类如何写:

FlyingHelper.h

 1 #ifndef _FlyingHelper_H_
 2 #define _FlyingHelper_H_
 3 
 4 // INCLUDES -----------------------------------------------------------------------------
 5 
 6 #include "..\DemoGL.h"
 7 
 8 // --------------------------------------------------------------------------------------
 9 
10 class CFlyingHelper : public CDemoGL
11 {
12 public:
13     CFlyingHelper();
14 
15     ~CFlyingHelper();
16 
17     // 对该对象类型的判断
18     WHY_DEFINE_IS_KIND_OF(CFlyingHelper, CDemoGL);
19 
20     // 初始化处理
21     bool            Initialize();
22 
23     // 销毁处理(删除创建的对象,恢复GL设备状态)
24     void            Destroy();
25 
26     // 执行,用于对逻辑的处理
27     void            Execute(Yuint deltaTime);
28 
29     // 渲染
30     void            Render();
31 
32     // UI界面的渲染
33     void            RenderUI();
34 
35     // Windows系统消息响应
36     bool            ProcessSystemMessage(Yuint, Yuint, Yuint);
37 
38     // 返回功能说明
39     const char*     GetTip() const
40     {
41         return "Flying Helper: Tell you how to create a demo.";
42     }
43 
44     // 对GL设备状态的设置
45     void            InitGLStates();
46 
47     // 键盘事件响应
48     void            OnKeyDown(Yuint key);
49 
50     // 鼠标左键按下响应
51     void            OnMouseDown(short x, short y);
52 
53     // 鼠标左键弹起响应
54     void            OnMouseUp(short x, short y);
55 
56     // 鼠标移动事件响应
57     void            OnMouseMove(short x, short y);
58 
59     // 窗口大小变化响应
60     void            OnResize(Yuint width, Yuint height);
61 
62 private:
63     short m_mouseX;
64     short m_mouseY;
65     bool m_bMouseDown;
66 };
67 
68 // --------------------------------------------------------------------------------------
69 
70 #endif
View Code

FlyingHelper.cpp

  1 // --------------------------------------------------------------------------------------
  2 
  3 #include "..\..\..\WhyEngine\YInterface\WhyModuleAPI.h"
  4 #include "..\..\..\Interface\YicGLDevice.h"
  5 #include "..\..\..\Interface\YicGLFont.h"
  6 #include "..\..\..\Interface\YicGLPrimitive2DRender.h"
  7 #include <gl\gl.h>            // Header File For The OpenGL32 Library
  8 #include <gl\glu.h>            // Header File For The GLu32 Library
  9 #include "FlyingHelper.h"
 10 
 11 // --------------------------------------------------------------------------------------
 12 
 13 #ifndef WM_MOUSEWHEEL
 14   #define WM_MOUSEWHEEL                 0x020A
 15 #endif
 16 
 17 // --------------------------------------------------------------------------------------
 18 
 19 // 将实体对象注册到引擎(非常重要)
 20 WHY_REGISTER_ENTITY(CFlyingHelper)
 21 
 22 // --------------------------------------------------------------------------------------
 23 
 24 CFlyingHelper::CFlyingHelper()
 25 {
 26     m_mouseX = 0;
 27     m_mouseY = 0;
 28     m_bMouseDown = false;
 29 }
 30 
 31 CFlyingHelper::~CFlyingHelper()
 32 {
 33 }
 34 
 35 // 初始化处理
 36 bool            CFlyingHelper::Initialize()
 37 {
 38     if (!CDemoGL::Initialize())
 39     {
 40         return false;
 41     }
 42     
 43     // .......
 44 
 45     // 注册引擎的系统消息层
 46     _WHY_CORE->RegisterEntityLayer(this, YE_ELAYER_WINDOWS_MESSAGE, 0x80000000);
 47 
 48     return true;
 49 }
 50 
 51 // 销毁处理(删除创建的对象,恢复GL设备状态)
 52 void            CFlyingHelper::Destroy()
 53 {
 54     // .......
 55 
 56     CDemoGL::Destroy();
 57 }
 58 
 59 // 执行,用于对逻辑的处理(每帧都会被执行一次)
 60 void            CFlyingHelper::Execute(Yuint deltaTime)
 61 {
 62     // .......
 63 }
 64 
 65 // 渲染(每帧都会被执行一次)
 66 void            CFlyingHelper::Render()
 67 {
 68     // .......
 69 }
 70 
 71 // UI界面的渲染(每帧都会被执行一次)
 72 void            CFlyingHelper::RenderUI()
 73 {
 74     CDemoGL::RenderUI();
 75     
 76     char szPos[64];
 77     sprintf(szPos, "(%d, %d)", m_mouseX, m_mouseY);
 78     unsigned int color = (m_bMouseDown) ? 0xffff0000 : 0xff00ff00;
 79     m_pGLFont->DrawText2D(m_mouseX, m_mouseY, color, szPos);
 80 }
 81 
 82 // Windows系统消息响应
 83 bool            CFlyingHelper::ProcessSystemMessage(Yuint iMsg, Yuint wParam, Yuint lParam)
 84 {
 85     switch (iMsg)
 86     {
 87     case WM_SIZE:
 88         break;
 89     case WM_KEYDOWN:
 90         break;
 91     case WM_LBUTTONDOWN:
 92         break;
 93     case WM_LBUTTONUP:
 94         break;
 95     case WM_RBUTTONDOWN:
 96         break;
 97     case WM_RBUTTONUP:
 98         break;
 99     case WM_MOUSEMOVE:
100         break;
101     case WM_MOUSEWHEEL:
102         break;
103     }
104 
105     return false;
106 }
107 
108 // 对GL设备状态的设置
109 void            CFlyingHelper::InitGLStates()
110 {
111     // .......
112 }
113 
114 // 键盘事件响应
115 void            CFlyingHelper::OnKeyDown(Yuint key)
116 {
117     char c[4];
118     c[0] = (char)key;
119     c[1] = '\r';
120     c[2] = '\n';
121     c[3] = 0;
122     ::OutputDebugStringA(c);
123 }
124 
125 // 鼠标左键按下响应
126 void            CFlyingHelper::OnMouseDown(short x, short y)
127 {
128     m_bMouseDown = true;
129 }
130 
131 // 鼠标左键弹起响应
132 void            CFlyingHelper::OnMouseUp(short x, short y)
133 {
134     m_bMouseDown = false;
135 }
136 
137 // 鼠标移动事件响应
138 void            CFlyingHelper::OnMouseMove(short x, short y)
139 {
140     m_mouseX = x;
141     m_mouseY = y;
142 }
143 
144 // 窗口大小变化响应
145 void            CFlyingHelper::OnResize(Yuint width, Yuint height)
146 {
147     CDemoGL::OnResize(width, height);
148 
149     // .......
150 }
View Code

代码中"// ......."的部分是由用户改写的.

 

源码下载地址:
http://pan.baidu.com/s/1bniWD0z

源码中有4个模块,

"SampleWin"和"WhyDemoViewer"为Windows应用程序.

"WhyGLDevice"为OpenGL的设备创建模块,里面还实现了字体的显示功能和简单二维图形显示的功能.

"WhyTestGL"为具体的DEMO逻辑,用户可以在这里添加自己的代码.

程序中还需要一个模块WhyCore这是我引擎的核心,用于对其他模块的加载管理,不过我尚没有将其开源的打算.

 

接下来要说下程序需要的两个配置文件

WhyCore.ini是引擎的启动文件

ModulesPath = .\dll\DumpProcess = true
CreateDumpFile = true
WriteDumpLog = true
MaxNumStackFrame = 10Game = CWhyTestGL[WhyTestGL]
;DemoGL = CFlying01
[WhyTestGL]
DemoGL = CFlying01 这个表示初始时将启动哪一个DEMO,CFlying01为一个DEMO对象的类名.用该方法在调试程序时比较方便.
前面加分号;表示该行无效.

WhyTestGL.ini是DEMO的配置文件
[WhyTestGL]
Nehe = OpenGL-Nehe OpenGL tutorials most of the source data sets to help you from entry to proficient in OpenGL
Flying = WhyEngine Demo[Nehe]
CNeheLesson01 = Press any key to change background color
CNeheLesson02 = My First Polygon, Draw Triangle and Quad
.........
CNeheLesson47 = CG Vertex Shader
CNeheLesson48 = ArcBall Rotation[Flying]
CFlyingHelper = Flying Helper: Tell you how to create a demo
CFlying01 = Test YicGLPrimitive2DRender and draw some 2D graph

这里的]表示DEMO分为几组.

然后每个字段下是DEMO对象的类名以及对应的相关信息.

用户如果写了自己的DEMO,请务必在WhyTestGL.INI配置文件中添加上相关信息.

-------------------------------------------------------------------------------------
最后要说的是,这个东西写得很仓促,如果有什么BUG,请与我联系.

[Nehe]
CNeheLesson01 OpenGL窗口 Press any key to change background color

CNeheLesson02 多边形 My First Polygon, Draw Triangle and Quad

CNeheLesson03 添加颜色 Adding Color

CNeheLesson04 旋转 Rotation

CNeheLesson05 3D空间 3D Shapes: Pyramid and Box

CNeheLesson06 纹理映射 Texture Mapping

CNeheLesson07 光照和键盘 Texture Filters, Lighting & Keyboard Control

CNeheLesson08 混合 Blending

CNeheLesson09 移动图像 Moving Bitmaps In 3D Space

CNeheLesson10 3D世界 Loading And Moving Through A 3D World

CNeheLesson11 飘动的旗帜 Flag Effect (Waving Texture)

CNeheLesson12 显示列表 Display List

CNeheLesson13 2D字体 Draw Text

CNeheLesson14 3D字体 Draw 3D Text

CNeheLesson15 纹理图形字 Texture Mapped Outline Fonts

CNeheLesson16 雾 Cool Looking Fog

CNeheLesson17 2D图像文字 2D Texture Font

CNeheLesson18 二次几何体 Quadric Geometry

CNeheLesson19 粒子系统 Particle Engine Using Triangle Strips

CNeheLesson20 蒙板 Masking

CNeheLesson21 线的游戏 Game Crazy Grid. Lines, Antialiasing, Timing, Ortho View And Simple Sounds

CNeheLesson22 凹凸映射 Bump-Mapping, Multi-Texturing & Extensions

CNeheLesson23 球面映射 Sphere Mapping Quadrics In OpenGL

CNeheLesson24 扩展TGA纹理 Tokens, Extensions, Scissor Testing And TGA Loading

CNeheLesson25 变形 Morphing & Loading Objects From A File

CNeheLesson26 反射 Clipping & Reflections Using The Stencil Buffer

CNeheLesson27 影子 Shadows

CNeheLesson28 贝塞尔曲面 Bezier Patches / Fullscreen Fix

CNeheLesson29 Blt函数 Blitter Function, RAW Texture Loading

CNeheLesson30 碰撞检测 Collision Detection

CNeheLesson31 模型加载 Model Loading

CNeheLesson32 拾取游戏 Shoot Game. Picking, Alpha Blending, Alpha Testing, Sorting

CNeheLesson33 TGA文件 Loading Compressed And Uncompressed TGA's

CNeheLesson34 地形 Beautiful Landscapes By Means Of Height Mapping

CNeheLesson35 播放AVI Playing AVI Files In OpenGL

CNeheLesson36 渲染到纹理 Radial Blur & Rendering To A Texture

CNeheLesson37 卡通映射 Cel-Shading

CNeheLesson38 资源文件 Butterfly Texturing Triangles

CNeheLesson39 物理模拟 Introduction to Physical Simulations

CNeheLesson40 绳子的模拟 Rope Physics

CNeheLesson41 体积雾气 Volumetric Fog & IPicture Image Loading

CNeheLesson42 多重视口 Multiple Viewports

CNeheLesson43 FreeType库 FreeType Fonts in OpenGL

CNeheLesson44 3D 光晕 3D Lens Flare With Occlusion Testing

CNeheLesson45 顶点缓存 Vertex Buffer Objects

CNeheLesson46 全屏反走样 Fullscreen AntiAliasing

CNeheLesson47 CG顶点脚本 CG Vertex Shader

CNeheLesson48 轨迹球 ArcBall Rotation


[Flying]
CFlyingHelper = Flying Helper: Tell you how to create a demo

CFlying01 = Test YicGLPrimitive2DRender and draw some 2D graph

转载于:https://www.cnblogs.com/WhyEngine/p/3632858.html

相关文章:

iOS与JS交互的4种方法

iOS与JS交互的方法&#xff1a; 1.拦截url&#xff08;适用于UIWebView和WKWebView&#xff09; 2.JavaScriptCore&#xff08;只适用于UIWebView&#xff0c;iOS7&#xff09; 3.WKScriptMessageHandler&#xff08;只适用于WKWebView&#xff0c;iOS8&#xff09; 4.WebV…

UDP打洞原理

1. NAT分类根据Stun协议(RFC3489),NAT大致分为下面四类1) Full Cone这种NAT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A.不管是不是C发过来的.例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88A(192.168…

五款常用协议分析处理工具推荐

工欲善其事&#xff0c;必先利其器&#xff0c;一款好的工具&#xff0c;能取到事半功倍的效果。进行协议分析&#xff0c;好的辅助工具必不可少&#xff0c;本文推荐五款最常用且易用的协议分析工具给大家&#xff0c;包括两款综合抓包及分析工具&#xff0c;一款协议重放工具…

【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

关键词&#xff1a;android 电池 电量计 MAX17040 任务初始化宏 power_supply 平台信息:内核&#xff1a;linux2.6/linux3.0系统&#xff1a;android/android4.0 平台&#xff1a;samsung exynos 4210、exynos 4412 、exynos 5250 作者&#xff1a;xubin341719(欢迎转载&…

hihoCoder#1384 : Genius ACM

对于一个固定的区间$[l,r]$&#xff0c;显然只要将里面的数字从小到大排序后将最小的$m$个和最大的$m$个配对即可。 如果固定左端点&#xff0c;那么随着右端点的右移&#xff0c;$SPD$值单调不降&#xff0c;所以尽量把右端点往右移&#xff0c;贪心分割即可。 为了使得扫过的…

微信小程序开发 笔记

1.[wxss]设置带透明度的rgb颜色&#xff1a;rgb(0,0,0,0.5); 2.小程序使用类似于iOS的NSNotification&#xff1a;&#xff08;第三方:https://github.com/icindy/WxNotificationCenter&#xff09; (1)在需要收发通知的页面引入WxNotificationCenter&#xff1a; var WxNotifi…

简单两行,实现无线WiFi共享上网,手机抓包再也不用愁了

你是否为WiFi共享而发愁&#xff0c;各个无线共享软件&#xff0c;某某共享精灵&#xff0c;某某免费WiFi&#xff0c;某某共享大师&#xff0c;某某随身WiFi&#xff0c;一个比一个难用&#xff0c;一个比一个私货多&#xff0c;一个比一个广告多&#xff0c;如果装上了它们&a…

用C#实现的条形码和二维码编码解码器

本篇介绍可以在C#中使用的1D/2D编码解码器。条形码的应用已经非常普遍&#xff0c;几乎所有超市里面的商品上面都印有条形码&#xff1b;二维码也开始应用到很多场合&#xff0c;如火车票有二维码识别、网易的首页有二维码图标&#xff0c;用户只需要用手机扫描一下就可以看到手…

【iOS】通过NSURLProtocol提高Web加载速度

一.项目需求 项目中有个海报功能&#xff0c;是用UIWebView加载h5网页的形式。因为海报的使用率比较高&#xff0c;如果网页加载得比较慢会严重影响用户体验&#xff0c;因此我们想了一个方法&#xff0c;在用户启动APP后&#xff0c;如果连接了Wi-Fi&#xff0c;就将一些css和…

rand()和srand()关系很简单——一看就明白(通过一个可移植的源码)

1 函数rand和srand实现及描述 #include <stdlib.h> //供rand()使用的种子数&#xff0c;初值为1 unsigned long int next 1; /* * 描述&#xff1a;函数rand() 用于生成介于 0和RAND_MAX之间的伪随机整数序列 * 其中RAND_MAX是在头文件<stdlib.h> 中定义的…

Windows下Python 3.6 安装BeautifulSoup库

“ 介绍Python库BeautifulSoup安装。”01—BeautifulSoup库介绍Beautiful Soup是Python的一个库&#xff0c;支持Python 2和Python 3,最主要的功能是从网页抓取数据&#xff0c;即爬虫,官网介绍如下&#xff1a;Beautiful Soup provides a few simple methods and Pythonic idi…

struts2配置详解

01.Struts 2基本结构 使用Struts2框架实现用登录的功能&#xff0c;使用struts2标签和ognl表达式简化了试图的开发&#xff0c;并且利用struts2提供的特性对输入的数据进行验证&#xff0c;以及访问ServletAPI时实现用户会话跟踪&#xff0c;其简单的程序运行流程图如下 Struts…

Xcode调试技巧

1、给断点设定触发条件 如下代码&#xff0c;右键断点&#xff0c;选择Edit Breakpoint&#xff0c;设定只有i8时&#xff0c;才触发断点。 此时只有i8时&#xff0c;才触发断点。 2、断点调试时修改变量 上面代码i8成立时&#xff0c;触发短点&#xff0c;此时右击变量窗口…

MiniGUI - UNIX Domain Socket 封装

/* Returns fd if all OK, -1 on error. */ int serv_listen (const char* name);服务器调用该函数建立一个监听套接字&#xff0c;并返回套接字文件描述符。建议将服务器监听套接字建立在 /var/tmp/ 目录下。MAX_NR_LISTEN_FD 宏定义了系统能够监听的最多文件描述符数&#xf…

RSA加密算法破解及原理

“ RSA加密算法是一种非对称加密算法&#xff0c;目前被广泛应用。本文介绍RSA算法的基本原理和破解方法。”RSA在互联网上被广泛应用&#xff0c;典型的如各个网站的证书。很多应用数据的加密也是使用RSA。本文介绍RSA算法的原理&#xff0c;并介绍其破解方法和工具。01—RSA算…

SpringMvc之@RequestParam详解

RequestParam是传递参数的. RequestParam用于将请求参数区数据映射到功能处理方法的参数上。 public String queryUserName(RequestParam String userName) 在url中输入:localhost:8080/**/?userNamezhangsan 请求中包含username参数&#xff08;如/requestparam1?userNamezh…

MLeaksFinder简单实现原理

MLeaksFinder是 iOS 平台的自动内存泄漏检测工具&#xff0c;下面以demo来实现检测视图控制器是否内存泄漏&#xff0c;实现类似的功能&#xff0c;简单地了解MLeaksFinder的原理。 总体思路&#xff1a;在视图控制器弹出栈 && 视图完全消失时&#xff0c;监听对象是否…

CSipSimple 工程分析 1

有两种方法,但是个人只有一种方法可以实现build并且生成应用,那么就是直接下载Google Code CSipSimple中提供已经设置好所有的配置的额\ubuntu虚拟机镜像文件. 打开这个镜像文件需要virtual Box,这个在oracle官方网站上面有,是个免费开源的软件. Google Code : https://code.go…

干货,Wireshark使用技巧-过滤规则

“介绍Wireshark抓包时使用的过滤规则。”熟练使用Wireshark&#xff0c;对协议分析大有帮助。本文介绍抓取报文时使用的过滤规则和对已有报文的显示进行控制的显示规则。01—过滤规则使用在抓取报文时使用的规则&#xff0c;称为过滤规则&#xff0c;Wireshark底层是基于Winpc…

《图解HTTP》笔记之TCP/IP

TCP/IP 通常使用的网络&#xff08;包括互联网&#xff09;是在TCP/IP协议族的基础上运作的。把互联网相关联的协议集合起来总称为TCP/IP。而HTTP属于它内部的一个子集&#xff08;HTTP协议是建立在TCP协议之上的一种应用&#xff09;&#xff1a; TCP/IP协议族里最重要的一…

JS --正则表达式验证、实战之邮箱模式

JS验证格式&#xff1a;提高用户体验&#xff0c;验证文本。需要防止程序员的代码结构更改攻击&#xff0c;因为web段的代码有可能会被更改&#xff0c;更改后JS有可能会验证不住那么&#xff0c;C#端在JS段通过验证的情况下&#xff0c;还需要进行二次验证 <body><fo…

《ASP.NET MVC4 WEB编程》学习笔记------Web API 续

目录 ASP.NET WEB API的出现缘由 ASP.NET WEB API的强大功能 ASP.NET WEB API的出现缘由 随着UI AJAX 请求适量的增加&#xff0c;ASP.NET MVC基于JsonResult的控制器操作将无法满足高级AJAX前端的需求。如果真的出现这种情况&#xff0c;就应该好好寻找一种更简单&#xff0c;…

干货:Wireshark使用技巧-显示规则

“ 介绍Wireshark对已有报文的显示进行控制的显示规则。”之前对Wireshark抓包时使用的过滤规则进行了介绍&#xff0c;本文介绍对已有报文的显示进行控制的显示规则。掌握了显示规则&#xff0c;你使用Wireshark的动作都会炫起来。点击回顾&#xff1a;过滤规则01—显示规则使…

【转载】Linux系统与性能监控

原文: Linux System and Performance Monitoring Darren Hoch 译:Roger 这是[叔度]给我的一篇非常不错的关于Linux性能监控的文档&#xff0c;可惜是英文的&#xff0c;网上只能找到些中文节选&#xff0c;并不完整。 准备花些时间将原文共43页认真学习一下&#xff0c;顺便翻译…

iOS端Socket连接、发送数据(一)

一、Socket的应用 IM即时通讯是通过Socket的方式实现长连接&#xff0c;可运用于 &#xff08;1&#xff09;直播聊天室、礼物 &#xff08;2&#xff09;微信、QQ等即时聊天 &#xff08;3&#xff09;游戏对话、技能等 二、SOCKET原理 套接字&#xff08;socket&#x…

dataTable 从服务器获取数据源的两种表现形式

1 var table $(#example1).DataTable({2 "processing": true,//加载效果3 "autoWidth": false,4 "iDisplayLength": 25,//设置每页要显示的条数5 "lengthMenu": [[25, 50, 100], [25, 50, 100]],//设…

干货!链家二手房数据抓取及内容解析要点

“本文对链家官网网页进行内容分析&#xff0c;可以作为一般HTTP类应用协议进行协议分析的参考&#xff0c;同时&#xff0c;对链家官网的结构了解后&#xff0c;可以对二手房相关信息进行爬取&#xff0c;并且获取被隐藏的近期成交信息。”另外&#xff0c;近期将对包含登录帐…

Atitit.软件兼容性原理与实践 v3 q326.docx

Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api vs 修改旧的api1 3. Web方面的兼容性&#xff08;js&#xff0c;html&#xff09;1 3.1. Threadlocal2 4. 数据库表兼容性2 4.1. 2. 扩展表模式2 5. 兼容性策略2 5.1. Atitit.兼容性的“一…

用PULL解析器解析XML文件

第一种方式&#xff08;简洁&#xff0c;直接用pullparser.nextText()来返回下一个String类型的值&#xff09;&#xff1a; 1 package lee.service; 2 3 import java.io.InputStream; 4 import java.util.ArrayList; 5 import java.util.List; 6 import org.xmlpull…

iOS端Socket(二)ProtocolBuffer使用

ProtocolBuffer使用 一、环境及ProtocolBuffer的安装 分别在终端执行以下命令&#xff1a; ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"brew install protobuf-swift brew install automake brew install libtoo…