臺(tái)簡(jiǎn)介: emsite框架是一個(gè)分布式的后臺(tái)全自動(dòng)快速開(kāi)發(fā)框架,采用dubbo作為服務(wù)層框架,后臺(tái)將集成單點(diǎn)登錄、Auth2.0、storm+kafka消息處理系統(tǒng)、kafka+ flume+storm+hdfs+hadoop作為日志分析系統(tǒng)、配置中心、分布式任務(wù)調(diào)度系統(tǒng)、服務(wù)器實(shí)時(shí)監(jiān)控系統(tǒng)、搜索引擎系統(tǒng)(elasticsearch)。以上各大功能將作為模塊化集成到本項(xiàng)目。
框架簡(jiǎn)介
1、系統(tǒng)管理模塊,包括組織架構(gòu)(用戶(hù)管理、機(jī)構(gòu)管理、區(qū)域管理)、菜單管理、角色權(quán)限管理、字典管理等功能; 2、代碼生成模塊,完成重復(fù)的工作; 3、全自動(dòng)增量發(fā)版,輕松完成版本快速迭代;
1、git服務(wù)器分支提交分析; 2、git提交日志分析; 3、svn服務(wù)器分支提交分析; 4、svn提交日志分析;
框架規(guī)劃
1、在線(xiàn)客服開(kāi)源系統(tǒng); 2、統(tǒng)一微信公眾號(hào)管理平臺(tái);
emsite生態(tài)圈
01、emsite框架(獨(dú)立主分支master) 02、emsite微信公眾號(hào)管理平臺(tái)(獨(dú)立分支wxdev) 03、emsite在線(xiàn)客服開(kāi)源系統(tǒng)(獨(dú)立項(xiàng)目:[emipre-ons-talk-parent](https://gitee.com/hackempire/empire-ons-talk-parent)) 04、emstie框架springboot+springcloud版本(獨(dú)立項(xiàng)目:[emsite-cloud](https://gitee.com/hackempire/emsite-cloud)) 05、emsite框架soa框架(獨(dú)立項(xiàng)目,遠(yuǎn)程RPC服務(wù)框架【服務(wù)熔斷、降級(jí)、限流、異步、分布式、全鏈路監(jiān)控】) 06、增量部署項(xiàng)目,支持git/gitee/svn(獨(dú)立項(xiàng)目:[patch-generator](https://gitee.com/hackempire/patch-generator-parent)) 07、增量部署桌面版項(xiàng)目,支持git/gitee/svn(獨(dú)立項(xiàng)目:[patch-generator-desk](https://gitee.com/hackempire/patch-generator-desk)) 08、全能監(jiān)控項(xiàng)目地址(獨(dú)立項(xiàng)目:[omnipotent-monitoring](https://gitee.com/hackempire/omnipotent-monitoring))
框架調(diào)整計(jì)劃表【歡迎有志者加盟】
一階段:
01、文檔整理更新,數(shù)據(jù)庫(kù)初始化excel和emsite-mysql.sql腳步同步更新[2018-02-07---2018-02-11]----已完成 02、JavaMelody和druid監(jiān)控的分布式支持?jǐn)U展[2018-02-07---2018-02-22]----執(zhí)行中(ing) 03、代碼優(yōu)化之vo、dto層分離[2018-02-23---2018-03-10]----已結(jié)束 04、poi文件導(dǎo)出、導(dǎo)入優(yōu)化解耦[2018-03-06---2018-03-15]----延期執(zhí)行 05、分布式任務(wù)調(diào)度系統(tǒng)集成[2018-03-01---2018-03-05]----延期執(zhí)行 06、kafka+flume+storm+hdfs+hadoop日志分析系統(tǒng)模塊功能開(kāi)發(fā)、當(dāng)前日志系統(tǒng)架構(gòu)優(yōu)化[2018-03-13---2018-04-01]----延期執(zhí)行 07、框架部署結(jié)構(gòu)動(dòng)靜分離調(diào)整[ngnix+httpd],框架文件系統(tǒng)圖片資源服務(wù)器架構(gòu)調(diào)整[fastDFS][2018-04-01---2018-04-10]----延期執(zhí)行 08、增量部署系統(tǒng)模塊開(kāi)發(fā)【SVN增量方案、GIT增量方案】----已完成 09、Apache ActiveMQ/Apache RocketMQ內(nèi)部消息系統(tǒng)集成 10、emsite框架配置優(yōu)化,集成配置中心 11、cas單點(diǎn)登錄、jwt權(quán)限集成 12、微信公眾號(hào)第三方平臺(tái)基礎(chǔ)功能開(kāi)發(fā)(公眾號(hào)管理、自定義菜單管理、粉絲管理、群發(fā)管理、素材管理)----計(jì)劃執(zhí)行 13、微信接口調(diào)用監(jiān)控功能開(kāi)發(fā) 14、在線(xiàn)客服開(kāi)源系統(tǒng) a.openfire+smack+微信h5+swing/javafx(待定)+sip服務(wù)器集成(待定)+軟硬電話(huà)集成+智能機(jī)器人 備選技術(shù): xmpp:Jabber、openfire sip:Asterisk、Cipango、FreeSwitch、SIPServer2008、opensips、Kamailio、OpenSER、sipXecx、miniSipServer、Brekeke、 GNU SIP Witch、Mobicents、Mysipswitch、SailFin、SIP Express Router、sipX、Yate、YXA 智能機(jī)器人:圖靈機(jī)器人、百度AI機(jī)器人、青云客智能聊天機(jī)器人 15、微信公眾平臺(tái)插件開(kāi)發(fā)(大轉(zhuǎn)盤(pán)、在線(xiàn)門(mén)店、微信論壇、微信商城) 16、Solr/Elasticsearch搜索引擎系統(tǒng)集成 17、Swagger2系統(tǒng)開(kāi)放Api接口文檔測(cè)試系統(tǒng)集成 18、系統(tǒng)架構(gòu)部署文檔、部署視頻教程、wiki文檔、系統(tǒng)模塊分析文檔完善等 19、Jenkins持續(xù)集成方案整理 20、遠(yuǎn)程RPC服務(wù)框架開(kāi)發(fā)【服務(wù)熔斷、降級(jí)、限流、異步、分布式、全鏈路監(jiān)控】 21、產(chǎn)品全線(xiàn)上線(xiàn)、開(kāi)啟框架培訓(xùn)社區(qū)、開(kāi)啟框架交流論壇 22、springboot+springcloud框架版本開(kāi)發(fā)----計(jì)劃執(zhí)行 23、Mybatis分頁(yè)插件PageHelper集成、分頁(yè)功能解耦----已完成 24、內(nèi)容管理模塊功能刪除----已完成
二階段
25、emsite后臺(tái)管理系統(tǒng)UI全新升級(jí)(備選方案:https://adminlte.io) 26、前后端分離架構(gòu)調(diào)整,框架版本2.0(node.js、bigpipe、KnockoutJS/AngularJS/vueJS/ReactJS待定) 27、dao層優(yōu)化,集成mybatis-plus----已擱置 28、Activiti工作流+在線(xiàn)OA系統(tǒng)模塊開(kāi)發(fā)----已擱置
emsite框架最新動(dòng)態(tài)
1.經(jīng)項(xiàng)目組研究討論,由于JavaMelody/druid等分布式擴(kuò)展后只支持內(nèi)外IP訪(fǎng)問(wèn)各臺(tái)服務(wù)器,且如需要支持外網(wǎng)分布式監(jiān)控,需要增加監(jiān) 控域名和Nginx搭配,故該條規(guī)劃已擱置,轉(zhuǎn)由zabbix server、Tomcat-manager、lambda probe進(jìn)行全方位監(jiān)控,后期將開(kāi)放以上三 個(gè)監(jiān)控方案的文檔至項(xiàng)目QQ群;另外本項(xiàng)目后期將考慮jmx自建部分組件的監(jiān)控體系,敬請(qǐng)期待[2018-02-18] 2.重大喜訊:阿里巴巴已將dubbo項(xiàng)目已正式成功捐獻(xiàn)給apache基金會(huì)孵化,由于apache目前還沒(méi)比dubbo更處理更有力的分布式服務(wù)框架 (soa),故預(yù)測(cè)dubbo將在不久成為apache頂級(jí)項(xiàng)目,且同spring cloud平分soa分布式服務(wù)的半壁江山[2018-02-18] 3.重要通知:由于本次dto和vo層改造忘記拉分支,所以將會(huì)直接在主分支上進(jìn)行,提交的代碼皆為可允許的代碼!如果想拉改造之前的代碼 請(qǐng)進(jìn)入項(xiàng)目標(biāo)簽中下載[2018-03-08] 4.最新通知:emsite-cloud項(xiàng)目正式立項(xiàng)(進(jìn)入技術(shù)調(diào)研籌備階段),將采用目前最火的技術(shù)springboot+springcloud來(lái)實(shí)現(xiàn),項(xiàng)目地址 https://gitee.com/hackempire/emsite-cloud[2018-03-08] 5.經(jīng)架構(gòu)分析,后臺(tái)管理系統(tǒng)部分不適合做dto層拆分.emsite架構(gòu)將采用前后端架構(gòu)分離,前臺(tái)(如微信h5功能)使用dto層作為數(shù)據(jù)傳輸對(duì)象, 后臺(tái)(如微信的數(shù)據(jù)管理)采用之前的entity作為數(shù)據(jù)傳輸對(duì)象.另外前后臺(tái)API隔離,前臺(tái)部分新開(kāi)發(fā)dubbo接口、dto等.[2018-03-20] 6.框架完成升級(jí)到j(luò)dk1.8,spring4.2.2.RELEASE,maven打包插件升級(jí)到最新版本,全自動(dòng)增量發(fā)版功能[2018-04-07] 7.增量打包桌面版已開(kāi)發(fā)完畢,正式發(fā)布版本2.0,請(qǐng)關(guān)注patch-generator-desk 項(xiàng)目地址:https://gitee.com/hackempire/patch-generator-desk[2018-05-01]
內(nèi)置功能
1、用戶(hù)管理:用戶(hù)是系統(tǒng)操作者,該功能主要完成系統(tǒng)用戶(hù)配置。 2、機(jī)構(gòu)管理:配置系統(tǒng)組織機(jī)構(gòu)(公司、部門(mén)、小組),樹(shù)結(jié)構(gòu)展現(xiàn),可隨意調(diào)整上下級(jí)。 3、區(qū)域管理:系統(tǒng)城市區(qū)域模型,如:國(guó)家、省市、地市、區(qū)縣的維護(hù)。 4、菜單管理:配置系統(tǒng)菜單,操作權(quán)限,按鈕權(quán)限標(biāo)識(shí)等。 5、角色管理:角色菜單權(quán)限分配、設(shè)置角色按機(jī)構(gòu)進(jìn)行數(shù)據(jù)范圍權(quán)限劃分。 6、字典管理:對(duì)系統(tǒng)中經(jīng)常使用的一些較為固定的數(shù)據(jù)進(jìn)行維護(hù),如:是否、男女、類(lèi)別、級(jí)別等。 7、操作日志:系統(tǒng)正常操作日志記錄和查詢(xún);系統(tǒng)異常信息日志記錄和查詢(xún)。 8、連接池監(jiān)視:監(jiān)視當(dāng)期系統(tǒng)數(shù)據(jù)庫(kù)連接池狀態(tài),可進(jìn)行分析SQL找出系統(tǒng)性能瓶頸。
為何選擇emsite
1、使用 Apache License 2.0 協(xié)議,源代碼完全開(kāi)源,無(wú)商業(yè)限制。 2、使用目前主流的Java EE開(kāi)發(fā)框架,簡(jiǎn)單易學(xué),學(xué)習(xí)成本低。 3、數(shù)據(jù)庫(kù)無(wú)限制,目前支持MySql、Oracle,可擴(kuò)充SQL Server、PostgreSQL、H2等。 4、模塊化設(shè)計(jì),層次結(jié)構(gòu)清晰。內(nèi)置一系列信息管理的基礎(chǔ)功能。 5、操作權(quán)限控制精密細(xì)致,對(duì)所有管理鏈接都進(jìn)行權(quán)限驗(yàn)證,可控制到按鈕。 6、數(shù)據(jù)權(quán)限控制精密細(xì)致,對(duì)指定數(shù)據(jù)集權(quán)限進(jìn)行過(guò)濾,七種數(shù)據(jù)權(quán)限可供選擇。 7、提供在線(xiàn)功能代碼生成工具,提高開(kāi)發(fā)效率及質(zhì)量。 8、提供常用工具類(lèi)封裝,日志、緩存、驗(yàn)證、字典、組織機(jī)構(gòu)等,常用標(biāo)簽(taglib),獲取當(dāng)前組織機(jī)構(gòu)、字典等數(shù)據(jù)。 9、兼容目前最流行瀏覽器(IE7+、Chrome、Firefox)。 10、最流行的分布式解決方案。 11、dubbo已正式進(jìn)入apache基金會(huì)孵化,前程似錦,可以說(shuō)已與spring cloud分別坐擁分布式服務(wù)框架的半壁江山.
技術(shù)選型
1、后端
a、核心框架:Spring Framework 4.2.2 b、分布式服務(wù)框架:dubbo2.5.8、dubbo-admin、dubbo-monitor c、分布式協(xié)調(diào)組件:zookeeper3.4.6 d、服務(wù)跟蹤:Hydra(京東) e、分布式配置:apollo(攜程)/disconf(百度)/diamond(阿里) d、安全框架:Apache Shiro 1.2 e、視圖框架:Spring MVC 4.2.2 f、服務(wù)端驗(yàn)證:Hibernate Validator 5.2 g、布局框架:SiteMesh 2.4 h、任務(wù)調(diào)度:Spring Task 4.2.2 i、持久層框架:MyBatis 3.2 j、數(shù)據(jù)庫(kù)連接池:Alibaba Druid 1.0 k、緩存框架:Ehcache 2.6、Redis l、日志管理:SLF4J 1.7、Log4j m、數(shù)據(jù)庫(kù)管理工具(備份、初始化):dbunit(當(dāng)前使用)、Flyway n、工具類(lèi):Apache Commons、Jackson 2.2、Xstream 1.4、Dozer 5.3、POI 3.9 o、監(jiān)控架構(gòu):zabbix server、Tomcat-manager、lambda probe、cat p、持續(xù)集成方案:Jenkins
2、前端
a、JS框架:jQuery 1.9。 b、CSS框架:Twitter Bootstrap 2.3.1(穩(wěn)定后臺(tái),UI方面根據(jù)需求自己升級(jí)改造吧)。 c、客戶(hù)端驗(yàn)證:JQuery Validation Plugin 1.11。 d、富文本在線(xiàn)編輯:CKEditor e、在線(xiàn)文件管理:CKFinder f、動(dòng)態(tài)頁(yè)簽:Jerichotab g、手機(jī)端框架:Jingle h、數(shù)據(jù)表格:jqGrid i、對(duì)話(huà)框:jQuery jBox j、下拉選擇框:jQuery Select2 k、樹(shù)結(jié)構(gòu)控件:jQuery zTree l、日期控件: My97DatePicker
3、平臺(tái)
a、服務(wù)器中間件:在Java EE 5規(guī)范(Servlet 3.0、JSP 2.1)下開(kāi)發(fā),支持應(yīng)用服務(wù)器中間件 有Tomcat 7+、Jboss 7+、 WebLogic 10+、WebSphere 8+。 b、數(shù)據(jù)庫(kù)支持:目前僅提供MySql或Oracle數(shù)據(jù)庫(kù)的支持,但不限于數(shù)據(jù)庫(kù),平臺(tái)留有其它數(shù)據(jù)庫(kù)支持接口, 你可以很方便 的更改為其它數(shù)據(jù)庫(kù),如:SqlServer 2008、MySql 5.5、H2等 c、開(kāi)發(fā)環(huán)境:Jdk1.7+(默認(rèn)jdk1.8)、(Eclipse Java EE 4.3|sts-3.6.2.RELEASE|myeclipse10)、Maven 3.2+、Git
安全考慮
a、開(kāi)發(fā)語(yǔ)言:系統(tǒng)采用Java 語(yǔ)言開(kāi)發(fā),具有卓越的通用性、高效性、平臺(tái)移植性和安全性。 b、分層設(shè)計(jì):(數(shù)據(jù)庫(kù)層,數(shù)據(jù)訪(fǎng)問(wèn)層,業(yè)務(wù)邏輯層,展示層)層次清楚,低耦合,各層必須通過(guò)接口才能接入并進(jìn)行參數(shù)校 驗(yàn)(如:在展示層不可直接操作數(shù)據(jù)庫(kù)),保證數(shù)據(jù)操作的安全。 c、雙重驗(yàn)證:用戶(hù)表單提交雙驗(yàn)證:包括服務(wù)器端驗(yàn)證及客戶(hù)端驗(yàn)證,防止用戶(hù)通過(guò)瀏覽器惡意修改(如不可寫(xiě)文本域、隱藏 變量篡改、上傳非法文件等),跳過(guò)客戶(hù)端驗(yàn)證操作數(shù)據(jù)庫(kù)。 d、安全編碼:用戶(hù)表單提交所有數(shù)據(jù),在服務(wù)器端都進(jìn)行安全編碼,防止用戶(hù)提交非法腳本及SQL注入獲取敏感數(shù)據(jù)等,確保數(shù)據(jù)安全。 e、密碼加密:登錄用戶(hù)密碼進(jìn)行SHA1散列加密,此加密方法是不可逆的。保證密文泄露后的安全問(wèn)題。 f、強(qiáng)制訪(fǎng)問(wèn):系統(tǒng)對(duì)所有管理端鏈接都進(jìn)行用戶(hù)身份權(quán)限驗(yàn)證,防止用戶(hù) g、服務(wù)監(jiān)控:系統(tǒng)采用dubbo的服務(wù)全鏈路監(jiān)控技術(shù)、可以做到精準(zhǔn)定位服務(wù)情況
快速體驗(yàn)
a、具備運(yùn)行環(huán)境:JDK1.7+、Maven3.2+(建議3.5.3)、MySql5+或Oracle10g+。 b、下載emsite-parent項(xiàng)目,導(dǎo)入第三方ckfinder插件jar包到本地maven庫(kù) c、修改src\main\resources\emsite.properties文件中的數(shù)據(jù)庫(kù)設(shè)置參數(shù)。 d、根據(jù)修改參數(shù)創(chuàng)建對(duì)應(yīng)MySql或Oracle數(shù)據(jù)庫(kù)用戶(hù)和參數(shù)。 e、新建數(shù)據(jù)庫(kù)emsite[字符集utf8 -- UTF-8 Unicode,排序規(guī)則utf8-bin],運(yùn)行db\init-db.bat腳本,即可導(dǎo)入表結(jié)構(gòu)及演示數(shù) 據(jù)(linux操作系統(tǒng):在控制臺(tái)中切換至項(xiàng)目根目錄,運(yùn)行命令:mvn antrun:run -Pinit-db);或者直接在數(shù)據(jù)庫(kù)工具中運(yùn)行emsite web項(xiàng)目db目錄下的emsite_mysql.sql文件。 f、啟動(dòng)redis,zookeeper組件 g、啟動(dòng)emsite-service-dbs數(shù)據(jù)服務(wù)層項(xiàng)目,使用eclipse maven啟動(dòng)命令:clean tomcat7:run(校驗(yàn):http://localhost:端口/emsite- service-dbs出現(xiàn)HelloWorld頁(yè)面) h、啟動(dòng)emsite web服務(wù)器項(xiàng)目,運(yùn)行目錄下bin\run-tomcat7.bat或bin\run-jetty.bat 或使用eclipse maven啟動(dòng)命令:clean tomcat7:run(第一次運(yùn)行,需要下載依賴(lài)jar包,請(qǐng)耐心等待,校驗(yàn):http://localhost:端口/emsite出現(xiàn)后臺(tái)登錄頁(yè)面)。 i、最高管理員賬號(hào),用戶(hù)名:emsite 密碼:admin
常見(jiàn)問(wèn)題
a、用一段時(shí)間提示內(nèi)存溢出,請(qǐng)修改JVM參數(shù):-Xmx512m -XX:MaxPermSize=256m b、有時(shí)出現(xiàn)文字亂碼:修改Tomcat的server.xml文件的Connector項(xiàng),增加URIEncoding="UTF-8" c、為什么新建菜單后看不到新建的菜單?因?yàn)槭跈?quán)問(wèn)題,菜單管理只允許最高管理員賬號(hào)管理(最高管理員默認(rèn)賬號(hào):emsite密碼:admin)。 d、第三方ckfinder導(dǎo)入方案[ckfinder包放在emsite項(xiàng)目下lib文件夾中] mvn install:install-file -DgroupId=com.ckfinder -DartifactId=ckfinder -Dversion=2.3 -Dpackaging=jar - Dfile=D:/thirdxsd/ckfinder-2.3.jar mvn install:install-file -DgroupId=com.ckfinder -DartifactId=ckfinderplugin-fileeditor -Dversion=2.3 -Dpackaging=jar - Dfile=D:/thirdxsd/ckfinderplugin-fileeditor-2.3.jar mvn install:install-file -DgroupId=com.ckfinder -DartifactId=ckfinderplugin-imageresize -Dversion=2.3 -Dpackaging=jar - Dfile=D:/thirdxsd/ckfinderplugin-imageresize-2.3.jar mvn install:install-file -DgroupId=com.empire -DartifactId=patch-generator -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar - Dfile=D:/thirdxsd/patch-generator-0.0.1-SNAPSHOT.jar e、項(xiàng)目類(lèi)文件報(bào)錯(cuò)或者jar包不存在 解決方法: 1.eclipse點(diǎn)擊project->clean->選擇emsite所有模塊->ok 2.選擇emsite-parent父項(xiàng)目->右鍵->debug as->maven -clean 3.選擇emsite-parent父項(xiàng)目->右鍵->debug as->maven -install 4.選中報(bào)emsite其它jar模塊引入失敗的項(xiàng)目->右鍵->maven->update project->選中online、force Update of Snapshots/Releases、 update project configuration from pom.xml、Refresh workspace resources from local filesystem、clean project等選項(xiàng) ->點(diǎn)擊ok 5.更新完成然后重復(fù)上面2、3步驟,問(wèn)題解決 f、maven報(bào)錯(cuò)Project configuration is not up-to-date with pom.xml錯(cuò)誤解決方法(導(dǎo)入項(xiàng)目之后發(fā)現(xiàn)有一個(gè)如下的錯(cuò)誤:Project configuration is not up-to-date with pom.xml. Run project configuration) update 其實(shí)這個(gè)問(wèn)題解決非常簡(jiǎn)單: 在項(xiàng)目上右鍵——【Maven】——【Update Project Configuration……】 這時(shí)會(huì)打開(kāi)一個(gè)(Update Maven Dependencies)的對(duì)話(huà)框,然后勾選住出錯(cuò)的項(xiàng)目,點(diǎn)擊Ok,這樣就搞定了。 g、dubbo服務(wù)鏈追蹤與監(jiān)控 下載dubbo-monitor或dubbo-admin監(jiān)控項(xiàng)目進(jìn)行部署 h、項(xiàng)目spring配置文件spring-context-dubbo.xml報(bào)錯(cuò)dubbo標(biāo)簽不支持,請(qǐng)用開(kāi)發(fā)工具關(guān)聯(lián)在emsite項(xiàng)目lib文件夾下面的dubbo.xsd. i、更換其它數(shù)據(jù)庫(kù)需修改配置文件emsite.property中數(shù)據(jù)庫(kù)連接配置,如果添加子項(xiàng)目模塊并且修改為其它數(shù)據(jù)庫(kù),需要新建Global并且覆蓋 emsite-service-common-api中Global類(lèi)的jdbcType方法用于支持?jǐn)?shù)據(jù)庫(kù)分頁(yè)插件. j、項(xiàng)目啟動(dòng)報(bào)dubbo配置的service無(wú)法啟動(dòng),刪除emsite->webapp->web-info->classes文件夾下面的所有文件 k、如果在jdk8中用maven-tomcat插件運(yùn)行項(xiàng)目報(bào)無(wú)效的1.8目標(biāo),請(qǐng)?jiān)诃h(huán)境中M2_HOME為最新apache-maven-3.5.3,并且將eclipse中jdk配置 Default VM agrments設(shè)置:-Dmaven.multiModuleProjectDirectory=M2_HOME
項(xiàng)目結(jié)構(gòu):
01、emsite-parent----------------maven-parent模塊 02、emsite-service-common-api----common-service-api 03、emsite-service-common-dbs----common-service-dbs 04、emsite-service-api-----------core-service-api 05、emsite-service-dbs-----------core-service-dbs 06、emsite-----------------------emsite-web后臺(tái)管理 07、emsite-patch-----------------emsite增量發(fā)版模塊
運(yùn)行效果:
運(yùn)行內(nèi)存:
spring-tool-suite(sts開(kāi)發(fā)工具)JVM配置如下:
-vmargs -Dosgi.requiredJavaVersion=1.6 -Xverify:none -Xms1536m -Xmx1536m -Xmn512m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Xnoclassgc -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:d:/sts-3.6.2.RELEASE/gc.log -Dorg.eclipse.swt.browser.IEVersion=10001 -Dcon.sun.management.jmxremote
1.emsite-service-dbs內(nèi)存效果圖:
2.emsite內(nèi)存效果圖
增量打包:
git地址:https://gitee.com/hackempire/emsite-parent
JeeSite是基于多個(gè)優(yōu)秀的開(kāi)源項(xiàng)目,高度整合封裝而成的高效,高性能,強(qiáng)安全性的開(kāi)源Java EE快速開(kāi)發(fā)平臺(tái)。
JeeSite本身是以Spring Framework為核心容器,Spring MVC為模型視圖控制器,MyBatis為數(shù)據(jù)訪(fǎng)問(wèn)層, Apache Shiro為權(quán)限授權(quán)層,Ehcahe對(duì)常用數(shù)據(jù)進(jìn)行緩存,Activit為工作流引擎。
JeeSite主要定位于企業(yè)信息化領(lǐng)域,已內(nèi)置企業(yè)信息化系統(tǒng)的基礎(chǔ)功能和高效的代碼生成工具,包括:系統(tǒng)權(quán)限組件、數(shù)據(jù)權(quán)限組件、數(shù)據(jù)字典組件、核心工具組件、視圖操作組件、工作流組件、代碼生成等。前端界面風(fēng)格采用了結(jié)構(gòu)簡(jiǎn)單、性能優(yōu)良、頁(yè)面美觀(guān)大氣的Twitter Bootstrap頁(yè)面展示框架。采用分層設(shè)計(jì)、雙重驗(yàn)證、提交數(shù)據(jù)安全編碼、密碼加密、訪(fǎng)問(wèn)驗(yàn)證、數(shù)據(jù)權(quán)限驗(yàn)證。使用Maven做項(xiàng)目管理,提高項(xiàng)目的易開(kāi)發(fā)性、擴(kuò)展性。
JeeSite目前包括以下三大模塊,系統(tǒng)管理(SYS)模塊、內(nèi)容管理(CMS)模塊、在線(xiàn)辦公(OA)模塊、代碼生成(GEN)模塊。 系統(tǒng)管理模塊 ,包括企業(yè)組織架構(gòu)(用戶(hù)管理、機(jī)構(gòu)管理、區(qū)域管理)、菜單管理、角色權(quán)限管理、字典管理等功能; 內(nèi)容管理模塊 ,包括內(nèi)容管理(文章、鏈接),欄目管理、站點(diǎn)管理、公共留言、文件管理、前端網(wǎng)站展示等功能; 在線(xiàn)辦公模塊 ,提供簡(jiǎn)單的請(qǐng)假流程實(shí)例。
JeeSite 提供了常用工具進(jìn)行封裝,包括日志工具、緩存工具、服務(wù)器端驗(yàn)證、數(shù)據(jù)字典、當(dāng)前組織機(jī)構(gòu)數(shù)據(jù)(用戶(hù)、機(jī)構(gòu)、區(qū)域)以及其它常用小工具等。另外還提供一個(gè)強(qiáng)大的在線(xiàn) 代碼生成 工具,此工具提供簡(jiǎn)單的單表、一對(duì)多、樹(shù)結(jié)構(gòu)功能的生成,如果對(duì)外觀(guān)要求不是很高,生成的功能就可以用了。如果你使用了JeeSite基礎(chǔ)框架,就可以很高效的快速開(kāi)發(fā)出,優(yōu)秀的信息管理系統(tǒng)。
1.用戶(hù)管理:用戶(hù)是系統(tǒng)操作者,該功能主要完成系統(tǒng)用戶(hù)配置。
2.機(jī)構(gòu)管理:配置系統(tǒng)組織機(jī)構(gòu)(公司、部門(mén)、小組),樹(shù)結(jié)構(gòu)展現(xiàn),可隨意調(diào)整上下級(jí)。
3.區(qū)域管理:系統(tǒng)城市區(qū)域模型,如:國(guó)家、省市、地市、區(qū)縣的維護(hù)。
4.菜單管理:配置系統(tǒng)菜單,操作權(quán)限,按鈕權(quán)限標(biāo)識(shí)等。
5.角色管理:角色菜單權(quán)限分配、設(shè)置角色按機(jī)構(gòu)進(jìn)行數(shù)據(jù)范圍權(quán)限劃分。
6.字典管理:對(duì)系統(tǒng)中經(jīng)常使用的一些較為固定的數(shù)據(jù)進(jìn)行維護(hù),如:是否、男女、類(lèi)別、級(jí)別等。
7.操作日志:系統(tǒng)正常操作日志記錄和查詢(xún);系統(tǒng)異常信息日志記錄和查詢(xún)。
8.連接池監(jiān)視:監(jiān)視當(dāng)期系統(tǒng)數(shù)據(jù)庫(kù)連接池狀態(tài),可進(jìn)行分析SQL找出系統(tǒng)性能瓶頸。
9.工作流引擎:實(shí)現(xiàn)業(yè)務(wù)工單流轉(zhuǎn)、在線(xiàn)流程設(shè)計(jì)器。
1.Eclipse IDE:采用Maven項(xiàng)目管理,模塊化。
2.在線(xiàn)演示:演示系統(tǒng)常用組件的使用代碼,內(nèi)嵌地圖案例等。
3.代碼生成:通過(guò)界面方式簡(jiǎn)單配置,自動(dòng)生成相應(yīng)代碼,目前包括三種生成方式(增刪改查):?jiǎn)伪怼⒁粚?duì)多、樹(shù)結(jié)構(gòu)。生成后的代碼如果不需要注意美觀(guān)程度,生成后即可用。
1、分層設(shè)計(jì):(數(shù)據(jù)訪(fǎng)問(wèn)層,業(yè)務(wù)邏輯層,展示層)層次清楚,低耦合,各層必須通過(guò)接口才能接入并進(jìn)行參數(shù)校驗(yàn)(如:在展示層不可直接操作數(shù)據(jù)庫(kù)),保證數(shù)據(jù)操作的安全。
2、雙重驗(yàn)證:用戶(hù)表單提交雙驗(yàn)證:包括服務(wù)器端驗(yàn)證及客戶(hù)端驗(yàn)證,防止用戶(hù)通過(guò)瀏覽器惡意修改(如不可寫(xiě)文本域、隱藏變量篡改、上傳非法文件等)而跳過(guò)客戶(hù)端驗(yàn)證操作數(shù)據(jù)庫(kù)。
3、安全編碼:用戶(hù)表單提交所有數(shù)據(jù),在服務(wù)器端都進(jìn)行安全編碼,防止用戶(hù)提交非法腳本及SQL注入獲取敏感數(shù)據(jù)等,確保數(shù)據(jù)安全。
4、密碼加密:登錄用戶(hù)密碼進(jìn)行SHA1散列加密,此加密方法是不可逆的。保證密文泄露后的安全問(wèn)題。
5、訪(fǎng)問(wèn)驗(yàn)證:系統(tǒng)對(duì)所有管理端鏈接都進(jìn)行用戶(hù)身份權(quán)限驗(yàn)證,防止用戶(hù)直接通過(guò)URL進(jìn)行未授權(quán)頁(yè)面。
6、數(shù)據(jù)驗(yàn)證:對(duì)指定數(shù)據(jù)集權(quán)限進(jìn)行過(guò)濾,七種數(shù)據(jù)權(quán)限可供選擇(所有權(quán)限,公司及子公司,本公司,部門(mén)及子部門(mén),本部門(mén),本人數(shù)據(jù),跨機(jī)構(gòu)數(shù)據(jù))
7、快速編碼:提供基本功能模塊的源代碼生成器,提高開(kāi)發(fā)效率及質(zhì)量。
1、后端
* 核心框架:Spring Framework 4.0
* 安全框架:Apache Shiro 1.2
* 視圖框架:Spring MVC 4.0
* 服務(wù)端驗(yàn)證:Hibernate Validator 5.1
* 布局框架:SiteMesh 2.4
* 工作流引擎:Activiti 5.15
* 任務(wù)調(diào)度:Spring Task 4.0
* 持久層框架:MyBatis 3.2
* 數(shù)據(jù)庫(kù)連接池:Alibaba Druid 1.0
* 緩存框架:Ehcache 2.6、Redis
* 日志管理:SLF4J 1.7、Log4j
* 工具類(lèi):Apache Commons、Jackson 2.2、Xstream 1.4、Dozer 5.3、POI 3.9
2、前端
* JS框架:JQuery 1.9。
* CSS框架:Twitter Bootstrap 2.3.1。
* 客戶(hù)端驗(yàn)證:JQuery Validation Plugin 1.11。
* 富文本:CKEcitor
* 文件管理:CKFinder
* 動(dòng)態(tài)頁(yè)簽:Jerichotab
* 手機(jī)端框架:Jingle
* 數(shù)據(jù)表格:jqGrid
* 對(duì)話(huà)框:jQuery jBox
* 下拉選擇框:jQuery Select2
* 樹(shù)結(jié)構(gòu)控件:jQuery zTree
* 日期控件: My97DatePicker
4、平臺(tái)
* 服務(wù)器中間件:在Java EE 5規(guī)范(Servlet 2.5、JSP 2.1)下開(kāi)發(fā),支持應(yīng)用服務(wù)器中間件
有Tomcat 6、Jboss 7、WebLogic 10、WebSphere 8。
* 數(shù)據(jù)庫(kù)支持:目前僅提供Oracle數(shù)據(jù)庫(kù)的支持,但不限于數(shù)據(jù)庫(kù),平臺(tái)留有其它數(shù)據(jù)庫(kù)支持接口,
可方便更改為其它數(shù)據(jù)庫(kù),如:SqlServer 2008、MySql 5.5、H2等
* 開(kāi)發(fā)環(huán)境:Java EE、Eclipse、Maven、Git
1.軟件工程基礎(chǔ)、Java語(yǔ)言基礎(chǔ)、JSP內(nèi)置對(duì)象、EL表達(dá)式
2.Spring Framework:類(lèi)的依賴(lài)、自動(dòng)注入、事務(wù)處理
3.Spring MVC:URL映射、參數(shù)傳遞
4.Apache Shiro:安全攔截方式,應(yīng)用方法,控制按鈕
5.SiteMesh:布局框架的用法
6.JSP標(biāo)準(zhǔn)標(biāo)簽庫(kù)(JSTL):if、choose、forEach、set
7.Spring MVC表單標(biāo)簽庫(kù):form、input、textarea、select、checkbox
8.文件存放規(guī)范,命名規(guī)范。
1.Spring Framework :
?跟我學(xué)Spring3
2.Spring MVC
?跟開(kāi)濤學(xué)Spring MVC
?JSP語(yǔ)法、Spring Form、JSTL、EL
?Bean Validation
3.Apache Shiro
?官方文檔
?快速入門(mén)
4.SiteMesh 2.4
?官方文檔
?入門(mén)實(shí)例、標(biāo)簽使用、裝飾文件
5.Bootstrap 2.3
?Bootstrap官網(wǎng)
?Bootstrap中文網(wǎng)
6.jQuery
?jQuery API:官方文檔 中文文檔
?jQuery Validation:官方文檔 使用范例
?jQuery zTree: 官方文檔
?jQruey jBox:官方文檔
7.Activiti
?官方網(wǎng)站
?中文文檔
?咖啡兔Activiti
8.Ehcache
?官方文檔
?EhCache分布式緩存
9.其它資料
?Alibaba Druid
?FreeMarker
?
1.運(yùn)行Maven目錄下的settings.bat文件,用來(lái)設(shè)置maven倉(cāng)庫(kù)路徑,并按提示操作(設(shè)置PATH系統(tǒng)變量、配置Eclipse)。
2.執(zhí)行jeesite/bin/eclipse.bat 生成工程文件并下載jar依賴(lài)包(如果需要修改默認(rèn)項(xiàng)目名,請(qǐng)打開(kāi)pom.xml修改第7行artifactId,然后再執(zhí)行eclipse.bat文件)。
3.將 jeesite 工程導(dǎo)入到eclipse,選中工程,按F5刷新。
4.設(shè)置數(shù)據(jù)源:src/main/resources/jeesite.properties
5.導(dǎo)入數(shù)據(jù)表并初始化數(shù)據(jù):運(yùn)行db/init-db.bat文件。(導(dǎo)入時(shí)如果出現(xiàn)“drop”失敗提示信息,請(qǐng)忽略。)
6.新建Server(Tomcat),注意選擇以下兩個(gè)選項(xiàng):
7.配置server.xml的Connector項(xiàng),增加URIEncoding="UTF-8"
8.部署到Tomcat,設(shè)置Auto Reload為Disabled。
9.訪(fǎng)問(wèn)工程:http://127.0.0.1:8080/ jeesite 用戶(hù)名:thinkgem 密碼:admin
9.常見(jiàn)問(wèn)題
1.'mvn' 不是內(nèi)部或外部命令,原因如下
a)PATH未配置或配置了多個(gè)不一致的Maven地址,如用戶(hù)/系統(tǒng)變量。
b)M2_HOME系統(tǒng)/用戶(hù)變量地址不正確,可刪除M2_HOME變量。
c)檢查mvn運(yùn)行是否正常,cmd執(zhí)行:mvn -v
2.運(yùn)行eclipse.bat 找不到文件路徑或亂碼:一般原因是路徑中包含空格或中文。
3.導(dǎo)入到eclipse下找不到j(luò)ar包:maven未配置,查看m2_repo倉(cāng)庫(kù)路徑是否正確。
4.運(yùn)行init-db.bat提示ORA-xxx:根據(jù)錯(cuò)誤碼排除錯(cuò)誤,一般是數(shù)據(jù)庫(kù)url不對(duì),用戶(hù)名或密碼錯(cuò)誤。
5.部署時(shí)出現(xiàn)某某被鎖定,一般原因:Tomcat服務(wù)中的兩個(gè)選項(xiàng)未選中。
6.字典列表,添加鍵值,出現(xiàn)亂碼:server.xml未配置url編碼為utf-8。
· 欄目列表:以樹(shù)結(jié)構(gòu)方式顯示網(wǎng)站整體設(shè)置的欄目,點(diǎn)擊在右側(cè)可管理當(dāng)前欄目的信息。
· 文章列表:當(dāng)前欄目如果為文章模型的話(huà),左側(cè)則顯示文章列表,如果為鏈接模型,左側(cè)則顯示鏈接列表。
· 內(nèi)容模型,包括:新聞文章、友情鏈接:
1、 文章模型:對(duì)新聞、資料進(jìn)行管理
1) 強(qiáng)大的可視化內(nèi)容在線(xiàn)編輯器:提供常用的內(nèi)容排版工具條;Word內(nèi)容直接復(fù)制,格式不亂;提供通用模板排版格式;圖片、Flash上傳及添加附件功能。
2) 文件管理:提供上傳的照片、文件增刪功能。
3) 關(guān)鍵字:提供文章關(guān)鍵字功能。
4) 權(quán)重:提供文章排序功能,值越大越靠前。
5) 縮略圖:文章縮略圖片。
6) 相關(guān)文章:關(guān)聯(lián)相關(guān)文章。
7) 推薦位:可推薦到首頁(yè)焦點(diǎn)圖、欄目文章推薦等。
8) 發(fā)布時(shí)間:可修改發(fā)布時(shí)間。
2、 鏈接模型:如友情鏈接內(nèi)容。
· 查詢(xún):可通過(guò)欄目選擇,文章標(biāo)題(模糊),文檔狀態(tài)查詢(xún)。
· 欄目列:點(diǎn)擊后可快速進(jìn)行查詢(xún)當(dāng)前點(diǎn)擊的欄目。
· 標(biāo)題列:點(diǎn)擊后可會(huì)計(jì)進(jìn)入文章查看或修改頁(yè)面。
· 操作列:提供文章的操作;
· 訪(fǎng)問(wèn):快速預(yù)覽發(fā)布后的頁(yè)面;
· 修改:進(jìn)行文章編輯修改
· 刪除:刪除當(dāng)前文章,刪除操作為邏輯刪除,刪除后在文章?tīng)顟B(tài)刪除中可查詢(xún)到,可恢復(fù)。
· 歸屬欄目:該欄目下有子欄目的不能選擇。
· 標(biāo)題:必填項(xiàng),文章標(biāo)題,最長(zhǎng)255個(gè)漢字;顏色:標(biāo)題顏色。
· 外部鏈接:如果當(dāng)前文章不是本站文檔,可選擇"外部鏈接"設(shè)置外部鏈接地址,打開(kāi)改文章時(shí)直接執(zhí)行改地址。
· 關(guān)鍵字:發(fā)布文章關(guān)鍵字信息,設(shè)置后顯示在頁(yè)面的關(guān)鍵字標(biāo)簽里,錄入可提高搜索引擎優(yōu)化排名。
· 權(quán)重:設(shè)置文章的排列順序,數(shù)值越大越靠前;可通過(guò)"置頂"復(fù)選框快速設(shè)置權(quán)重為999;也可通過(guò)設(shè)置"過(guò)期時(shí)間"設(shè)置置頂時(shí)間,超過(guò)指定時(shí)間后,置頂自動(dòng)失效,并設(shè)置為0;過(guò)期時(shí)間為空,表示不過(guò)期。
· 摘要:文章的摘要信息,不超過(guò)255個(gè)漢字。
· 縮略圖:提供文章圖片功能,如圖片新聞(438 × 268像素)等。
· 正文:文章的正文,可視化在線(xiàn)編輯器,提供常用的內(nèi)容排版工具條;Word內(nèi)容直接復(fù)制,格式不亂;提供通用模板排版格式;圖片、Flash上傳及添加附件功能。
· 添加圖片:可進(jìn)行從服務(wù)器上瀏覽一副以前上傳的圖片,也可鏈接其它網(wǎng)站圖片,可以自己手動(dòng)上傳一副圖片,操作界面如下:
· 添加附件:可進(jìn)行修改鏈接標(biāo)題,可服務(wù)器上選擇或手動(dòng)上傳(小于5M),同圖片,操作界面如下:
· 來(lái)源:填寫(xiě)文章的出處,來(lái)源等信息。
· 相關(guān)文章:可選擇與該文章相關(guān)的文章,提供閱讀者進(jìn)行延伸閱讀。
· 發(fā)布狀態(tài):文章的狀態(tài)(發(fā)布、審核、刪除),如果當(dāng)前登錄無(wú)發(fā)布權(quán)限,則直接進(jìn)入審核狀態(tài),文章審核后才可進(jìn)行正式發(fā)布。
· 查看評(píng)論:如果當(dāng)前為意見(jiàn)征集模塊,則可查看征集信息。
審核需要審核的文章,如通知通告,有信息員發(fā)布后,管理員可通過(guò)此功能對(duì)信息進(jìn)行審核發(fā)布。
統(tǒng)計(jì)一段時(shí)間內(nèi)的信息發(fā)布量及點(diǎn)擊量。
允許評(píng)論的文章,評(píng)論后需管理員進(jìn)行審核后才能展示到頁(yè)面上。有該功能的人員可對(duì)待審核的評(píng)論進(jìn)行審核操作。
樹(shù)形表格界面,可折疊;設(shè)置靈活,可隨意調(diào)整欄目父子關(guān)系;支持無(wú)限級(jí)子欄目;支持欄目排序;支持多種內(nèi)容模型(文章模型、鏈接模型等),支持上傳欄目縮了圖;支持設(shè)置欄目描述及關(guān)鍵字,提升搜索引擎排行。
1、 導(dǎo)航欄顯示:設(shè)置是否在網(wǎng)站主導(dǎo)航欄中顯示。
2、 分類(lèi)頁(yè)中顯示列表:是否在二級(jí)頁(yè)面中顯示內(nèi)容列表。
3、 展現(xiàn)方式:
1) 默認(rèn)方式:有子欄目,顯示子欄目?jī)?nèi)容列表;無(wú)子欄目,直接顯示該欄目的內(nèi)容列表。
2) 首欄目?jī)?nèi)容列表:顯示第一個(gè)子欄目的內(nèi)容列表。
3) 欄目第一條內(nèi)容:顯示該欄目中的第一篇內(nèi)容。
對(duì)站點(diǎn)進(jìn)行維護(hù),支持多站點(diǎn)發(fā)布,可設(shè)置站點(diǎn)標(biāo)題、描述、關(guān)鍵字、版權(quán)信息、模板風(fēng)格等。
當(dāng)存在多站點(diǎn)發(fā)布的情況下,可通過(guò)該功能進(jìn)行站點(diǎn)切換。
留言管理:姓名、郵箱、單位、電話(huà)、留言分類(lèi)(咨詢(xún)、建議、批評(píng)、其它)留言?xún)?nèi)容。
1、 進(jìn)入站點(diǎn)設(shè)置,并確定默認(rèn)站點(diǎn)為當(dāng)前站點(diǎn)。
2、 進(jìn)入欄目設(shè)置,給當(dāng)前站點(diǎn)設(shè)置和維護(hù)欄目,維護(hù)完成可訪(fǎng)問(wèn):http://127.0.0.1:8080/jeesite/f 預(yù)覽站點(diǎn)。
1、 完成數(shù)據(jù)維護(hù)下一步開(kāi)始新建站點(diǎn)主題風(fēng)格,進(jìn)入字典管理,給"內(nèi)容管理-站點(diǎn)主題 | cms_theme"字典,增加一個(gè)主題。
2、 進(jìn)入站點(diǎn)設(shè)置,設(shè)置默認(rèn)站點(diǎn)的:名稱(chēng)、描述、版權(quán)、主題(剛建立的主題)、首頁(yè)視圖等信息。
3、 復(fù)制 /src/main/webapp/WEB-INF/views/modules/cms/front/themes下的basic文件夾(為了對(duì)照方便,不要直接修改),重命名為自己設(shè)計(jì)的主題名稱(chēng)(剛建立的主題,字典鍵值)。
4、 到這里初始化工作基本完成,下一步開(kāi)始編輯你的主題文件即可。
1、 首頁(yè)模板:frontIndex.jsp, 命名格式:frontIndex*.jsp
2、 文章列表頁(yè):frontList.jsp, 命名格式:frontList*.jsp
3、 文章詳情頁(yè):frontViewArticle.jsp,命名格式:frontViewArticle*.jsp
4、 文章評(píng)論:frontComment.jsp
5、 公眾留言:frontGuestbook.jsp
6、 站點(diǎn)地圖:frontMap.jsp
7、 站點(diǎn)搜索:frontSearch.jsp
模板中的標(biāo)簽可參看fnc.tld文件。具體用法可參看以上模板文件;使用它,你可以不用動(dòng)后臺(tái)一處代碼,只需要修改你配置和模板文件,即可快速完成網(wǎng)站開(kāi)發(fā)。
14
https://github.com/thinkgem/jeesite
內(nèi)容管理模塊
功能說(shuō)明
ThinkGem
2014年6月17日
目錄1.管理功能31.1.內(nèi)容管理31.1.1.內(nèi)容發(fā)布31.1.2.統(tǒng)計(jì)分析81.1.3.評(píng)論管理81.1.4.欄目管理91.1.5.站點(diǎn)管理101.1.6.公共留言12
· 欄目列表:以樹(shù)結(jié)構(gòu)方式顯示網(wǎng)站整體設(shè)置的欄目,點(diǎn)擊在右側(cè)可管理當(dāng)前欄目的信息。
· 文章列表:當(dāng)前欄目如果為文章模型的話(huà),左側(cè)則顯示文章列表,如果為鏈接模型,左側(cè)則顯示鏈接列表。
· 內(nèi)容模型,包括:新聞文章、友情鏈接:
1、 文章模型:對(duì)新聞、資料進(jìn)行管理
1) 強(qiáng)大的可視化內(nèi)容在線(xiàn)編輯器:提供常用的內(nèi)容排版工具條;Word內(nèi)容直接復(fù)制,格式不亂;提供通用模板排版格式;圖片、Flash上傳及添加附件功能。
2) 文件管理:提供上傳的照片、文件增刪功能。
3) 關(guān)鍵字:提供文章關(guān)鍵字功能。
4) 權(quán)重:提供文章排序功能,值越大越靠前。
5) 縮略圖:文章縮略圖片。
6) 相關(guān)文章:關(guān)聯(lián)相關(guān)文章。
7) 推薦位:可推薦到首頁(yè)焦點(diǎn)圖、欄目文章推薦等。
8) 發(fā)布時(shí)間:可修改發(fā)布時(shí)間。
2、 鏈接模型:如友情鏈接內(nèi)容。
· 查詢(xún):可通過(guò)欄目選擇,文章標(biāo)題(模糊),文檔狀態(tài)查詢(xún)。
· 欄目列:點(diǎn)擊后可快速進(jìn)行查詢(xún)當(dāng)前點(diǎn)擊的欄目。
· 標(biāo)題列:點(diǎn)擊后可會(huì)計(jì)進(jìn)入文章查看或修改頁(yè)面。
· 操作列:提供文章的操作;
· 訪(fǎng)問(wèn):快速預(yù)覽發(fā)布后的頁(yè)面;
· 修改:進(jìn)行文章編輯修改
· 刪除:刪除當(dāng)前文章,刪除操作為邏輯刪除,刪除后在文章?tīng)顟B(tài)刪除中可查詢(xún)到,可恢復(fù)。
· 歸屬欄目:該欄目下有子欄目的不能選擇。
· 標(biāo)題:必填項(xiàng),文章標(biāo)題,最長(zhǎng)255個(gè)漢字;顏色:標(biāo)題顏色。
· 外部鏈接:如果當(dāng)前文章不是本站文檔,可選擇"外部鏈接"設(shè)置外部鏈接地址,打開(kāi)改文章時(shí)直接執(zhí)行改地址。
· 關(guān)鍵字:發(fā)布文章關(guān)鍵字信息,設(shè)置后顯示在頁(yè)面的關(guān)鍵字標(biāo)簽里,錄入可提高搜索引擎優(yōu)化排名。
· 權(quán)重:設(shè)置文章的排列順序,數(shù)值越大越靠前;可通過(guò)"置頂"復(fù)選框快速設(shè)置權(quán)重為999;也可通過(guò)設(shè)置"過(guò)期時(shí)間"設(shè)置置頂時(shí)間,超過(guò)指定時(shí)間后,置頂自動(dòng)失效,并設(shè)置為0;過(guò)期時(shí)間為空,表示不過(guò)期。
· 摘要:文章的摘要信息,不超過(guò)255個(gè)漢字。
· 縮略圖:提供文章圖片功能,如圖片新聞(438 × 268像素)等。
· 正文:文章的正文,可視化在線(xiàn)編輯器,提供常用的內(nèi)容排版工具條;Word內(nèi)容直接復(fù)制,格式不亂;提供通用模板排版格式;圖片、Flash上傳及添加附件功能。
· 添加圖片:可進(jìn)行從服務(wù)器上瀏覽一副以前上傳的圖片,也可鏈接其它網(wǎng)站圖片,可以自己手動(dòng)上傳一副圖片,操作界面如下:
· 添加附件:可進(jìn)行修改鏈接標(biāo)題,可服務(wù)器上選擇或手動(dòng)上傳(小于5M),同圖片,操作界面如下:
· 來(lái)源:填寫(xiě)文章的出處,來(lái)源等信息。
· 相關(guān)文章:可選擇與該文章相關(guān)的文章,提供閱讀者進(jìn)行延伸閱讀。
· 發(fā)布狀態(tài):文章的狀態(tài)(發(fā)布、審核、刪除),如果當(dāng)前登錄無(wú)發(fā)布權(quán)限,則直接進(jìn)入審核狀態(tài),文章審核后才可進(jìn)行正式發(fā)布。
· 查看評(píng)論:如果當(dāng)前為意見(jiàn)征集模塊,則可查看征集信息。
審核需要審核的文章,如通知通告,有信息員發(fā)布后,管理員可通過(guò)此功能對(duì)信息進(jìn)行審核發(fā)布。
統(tǒng)計(jì)一段時(shí)間內(nèi)的信息發(fā)布量及點(diǎn)擊量。
允許評(píng)論的文章,評(píng)論后需管理員進(jìn)行審核后才能展示到頁(yè)面上。有該功能的人員可對(duì)待審核的評(píng)論進(jìn)行審核操作。
樹(shù)形表格界面,可折疊;設(shè)置靈活,可隨意調(diào)整欄目父子關(guān)系;支持無(wú)限級(jí)子欄目;支持欄目排序;支持多種內(nèi)容模型(文章模型、鏈接模型等),支持上傳欄目縮了圖;支持設(shè)置欄目描述及關(guān)鍵字,提升搜索引擎排行。
1、 導(dǎo)航欄顯示:設(shè)置是否在網(wǎng)站主導(dǎo)航欄中顯示。
2、 分類(lèi)頁(yè)中顯示列表:是否在二級(jí)頁(yè)面中顯示內(nèi)容列表。
3、 展現(xiàn)方式:
1) 默認(rèn)方式:有子欄目,顯示子欄目?jī)?nèi)容列表;無(wú)子欄目,直接顯示該欄目的內(nèi)容列表。
2) 首欄目?jī)?nèi)容列表:顯示第一個(gè)子欄目的內(nèi)容列表。
3) 欄目第一條內(nèi)容:顯示該欄目中的第一篇內(nèi)容。
對(duì)站點(diǎn)進(jìn)行維護(hù),支持多站點(diǎn)發(fā)布,可設(shè)置站點(diǎn)標(biāo)題、描述、關(guān)鍵字、版權(quán)信息、模板風(fēng)格等。
當(dāng)存在多站點(diǎn)發(fā)布的情況下,可通過(guò)該功能進(jìn)行站點(diǎn)切換。
留言管理:姓名、郵箱、單位、電話(huà)、留言分類(lèi)(咨詢(xún)、建議、批評(píng)、其它)留言?xún)?nèi)容。
1、 進(jìn)入站點(diǎn)設(shè)置,并確定默認(rèn)站點(diǎn)為當(dāng)前站點(diǎn)。
2、 進(jìn)入欄目設(shè)置,給當(dāng)前站點(diǎn)設(shè)置和維護(hù)欄目,維護(hù)完成可訪(fǎng)問(wèn):http://127.0.0.1:8080/jeesite/f 預(yù)覽站點(diǎn)。
1、 完成數(shù)據(jù)維護(hù)下一步開(kāi)始新建站點(diǎn)主題風(fēng)格,進(jìn)入字典管理,給"內(nèi)容管理-站點(diǎn)主題 | cms_theme"字典,增加一個(gè)主題。
2、 進(jìn)入站點(diǎn)設(shè)置,設(shè)置默認(rèn)站點(diǎn)的:名稱(chēng)、描述、版權(quán)、主題(剛建立的主題)、首頁(yè)視圖等信息。
3、 復(fù)制 /src/main/webapp/WEB-INF/views/modules/cms/front/themes下的basic文件夾(為了對(duì)照方便,不要直接修改),重命名為自己設(shè)計(jì)的主題名稱(chēng)(剛建立的主題,字典鍵值)。
4、 到這里初始化工作基本完成,下一步開(kāi)始編輯你的主題文件即可。
1、 首頁(yè)模板:frontIndex.jsp, 命名格式:frontIndex*.jsp
2、 文章列表頁(yè):frontList.jsp, 命名格式:frontList*.jsp
3、 文章詳情頁(yè):frontViewArticle.jsp,命名格式:frontViewArticle*.jsp
4、 文章評(píng)論:frontComment.jsp
5、 公眾留言:frontGuestbook.jsp
6、 站點(diǎn)地圖:frontMap.jsp
7、 站點(diǎn)搜索:frontSearch.jsp
模板中的標(biāo)簽可參看fnc.tld文件。具體用法可參看以上模板文件;使用它,你可以不用動(dòng)后臺(tái)一處代碼,只需要修改你配置和模板文件,即可快速完成網(wǎng)站開(kāi)發(fā)。
者 | 天元浪子
責(zé)編 | 伍杏玲
出品 | CSDN 博客
【CSDN 編者按】OpenGL(開(kāi)放式圖形庫(kù)),用于渲染 2D、3D 矢量圖形的跨語(yǔ)言、跨平臺(tái)的應(yīng)用程序編程接口,C、C++、Python、Java等語(yǔ)言都能支持 OpenGL。本文作者以 Python 語(yǔ)法為例,用兩萬(wàn)字詳解 OpenGL 的理論知識(shí)、用法與實(shí)際操作,干貨滿(mǎn)滿(mǎn),一起來(lái)看看吧。
預(yù)備知識(shí)
OpenGL 是 Open Graphics Library 的簡(jiǎn)寫(xiě),意為“開(kāi)放式圖形庫(kù)”,是用于渲染 2D、3D 矢量圖形的跨語(yǔ)言、跨平臺(tái)的應(yīng)用程序編程接口(API)。OpenGL 不是一個(gè)獨(dú)立的平臺(tái),因此,它需要借助于一種編程語(yǔ)言才能被使用。C / C++ / Python / Java 都可以很好支持 OpengGL,我當(dāng)然習(xí)慣性選擇 Python 語(yǔ)言。
如果讀者是 Python 程序員,并且了解 NumPy,接下來(lái)的閱讀應(yīng)該不會(huì)有任何障礙;否則,我建議先花半小時(shí)學(xué)習(xí)一下 Python 語(yǔ)言。關(guān)于 Python ,可以參考我的另一篇博文《數(shù)學(xué)建模三劍客MSN》。事實(shí)上,我覺(jué)得 Python 語(yǔ)言近乎于自然語(yǔ)言,只要讀者是程序員,即便不熟悉 Python ,讀起來(lái)也不會(huì)有多大問(wèn)題。
另外,讀者也不必?fù)?dān)心數(shù)學(xué)問(wèn)題。使用 OpenGL 不需要具備多么高深的數(shù)學(xué)水平,只要能輔導(dǎo)初中學(xué)生的數(shù)學(xué)作業(yè),就足夠用了。
一、坐標(biāo)系
在 OpenGL 的世界里,有各式各樣的坐標(biāo)系。隨著對(duì) OpenGL 概念的理解,我們至少會(huì)接觸到六種坐標(biāo)系,而初始只需要了解其中的三個(gè)就足夠用了(第一次閱讀這段話(huà)的時(shí)候,只需要了解世界坐標(biāo)系就可以了)。
世界坐標(biāo)系(World Coordinates)
世界坐標(biāo)系是右手坐標(biāo)系,以屏幕中心為原點(diǎn)(0, 0, 0),且是始終不變的。
視點(diǎn)坐標(biāo)系(Eye or Camera Coordinates)
視點(diǎn)坐標(biāo)是以視點(diǎn)為原點(diǎn),以視線(xiàn)的方向?yàn)閆+軸正方向的坐標(biāo)系。OpenGL 管道會(huì)將世界坐標(biāo)先變換到視點(diǎn)坐標(biāo),然后進(jìn)行裁剪,只有在視線(xiàn)范圍(視景體)之內(nèi)的場(chǎng)景才會(huì)進(jìn)入下一階段的計(jì)算。
屏幕坐標(biāo)系(Window or Screen Coordinates)
OpenGL 的重要功能之一就是將三維的世界坐標(biāo)經(jīng)過(guò)變換、投影等計(jì)算,最終算出它在顯示設(shè)備上對(duì)應(yīng)的位置,這個(gè)位置就稱(chēng)為設(shè)備坐標(biāo)。在屏幕、打印機(jī)等設(shè)備上的坐標(biāo)是二維坐標(biāo)。值得一提的是,OpenGL 可以只使用設(shè)備的一部分進(jìn)行繪制,這個(gè)部分稱(chēng)為視區(qū)或視口(viewport)。投影得到的是視區(qū)內(nèi)的坐標(biāo)(投影坐標(biāo)),從投影坐標(biāo)到設(shè)備坐標(biāo)的計(jì)算過(guò)程就是設(shè)備變換了。
二、投影
三維場(chǎng)景中的物體最終都會(huì)顯示在類(lèi)似屏幕這樣的二維觀(guān)察平面上。將三維物體變?yōu)槎S圖形的變換成為投影變換。最常用的投影有兩種:平行投影和透視投影。如下圖所示,F(xiàn) 是投影面,p1p2 為三維空間中的一條直線(xiàn),p’1 和 p’2 分別是 p1 和 p2 在 F 上的投影,虛線(xiàn)表示投影線(xiàn),O 為投影中心。
平行投影
這里所說(shuō)的平行投影,特指正交平行投影——投影線(xiàn)垂直于投影面。將一個(gè)三維點(diǎn) (x,y,z) 正交平行投影到 xoy 平面上,則投影點(diǎn)坐標(biāo)為 (x,y,0)。由于平行投影丟棄了深度信息,所以無(wú)法產(chǎn)生真實(shí)感,但可以保持物體之間相對(duì)大小關(guān)系不變。
透視投影
透視投影將投影面置于觀(guān)察點(diǎn)和投影對(duì)象之間,距離觀(guān)察者越遠(yuǎn)的物體,投影尺寸越小,投影效果具有真實(shí)感,常用于游戲和仿真領(lǐng)域。
三、視景體
無(wú)論是平行投影還是透視投影,投影成像都是在投影面上——我們可以把投影面理解成顯示屏幕。世界坐標(biāo)系描述的三維空間是無(wú)限的,投影平面是無(wú)限的,但(我們能夠看到的)屏幕面積總是有限的,因此在投影變換時(shí),通常只處理能夠顯示在屏幕上的那一部分三維空間。從無(wú)限三維空間中裁切出來(lái)的可以顯示在屏幕上的部分三維空間,我們稱(chēng)之為視景體。視景體有六個(gè)面,分別是左右上下和前后面。
對(duì)于平行投影而言,視景體是一個(gè)矩形平行六面體;對(duì)于透視投影來(lái)說(shuō),視景體是一個(gè)棱臺(tái)。理解這一點(diǎn)并不難:因?yàn)樵竭h(yuǎn)處的物體在投影窗口的透視投影越小,也就意味著填滿(mǎn)投影窗口需要更大的體量,視景體自然就變成了棱臺(tái)。
四、視口
對(duì)于平行投影而言,視口就是由視景體的左右上下四個(gè)面圍成的矩形,對(duì)于透視投影來(lái)說(shuō),視口就是視景體的前截面在投影窗口上的透視投影。
視口是 OpenGL 中比較重要的概念,現(xiàn)階段可以簡(jiǎn)單理解成屏幕(或其他輸出設(shè)備)。事實(shí)上,視口和屏幕是相關(guān)但又不相同的,屏幕有固定的寬高比,而視口大小可以由用戶(hù)自行定義。通常,為了適應(yīng)不同寬高比的屏幕,在設(shè)置視口時(shí),會(huì)根據(jù)屏幕寬高比調(diào)整視景體(增加寬度或高度)。
五、視點(diǎn)
現(xiàn)實(shí)生活中,人們看到的三維空間物體的樣子取決于觀(guān)察者站在什么角度去看。這里面包含著三個(gè)概念:
觀(guān)察者的位置:眼睛在哪兒?
觀(guān)察者的姿勢(shì):站立還是倒立?左側(cè)臥還是右側(cè)臥?
觀(guān)察對(duì)象:眼睛盯著哪里?
對(duì)應(yīng)在 OpenGL 中,也有同樣的概念,即視點(diǎn)的位置、瞄準(zhǔn)方向的參考點(diǎn),以及(向上的)方向。
六、OpenGL 變換
下圖是三維圖形的顯示流程。世界坐標(biāo)系中的三維物體經(jīng)過(guò)視點(diǎn)變換和一系列幾何變換(平移、旋轉(zhuǎn)、縮放)之后,坐標(biāo)系變換為視點(diǎn)坐標(biāo)系;經(jīng)過(guò)投影和裁剪之后,坐標(biāo)系變換為歸一化設(shè)備坐標(biāo)系;最后經(jīng)過(guò)視口變換顯示在屏幕上,相應(yīng)地,坐標(biāo)系變成了窗口坐標(biāo)系。
視點(diǎn)變換:相當(dāng)于設(shè)置視點(diǎn)的位置和方向
模型變換:包括平移、旋轉(zhuǎn)、縮放等三種類(lèi)型
裁剪變換:根據(jù)視景體定義的六個(gè)面(和附加裁剪面)對(duì)三維空間裁剪
視口變換:將視景體內(nèi)投影的物體顯示在二維的視口平面上
安裝 PyOpenGL
如果想當(dāng)然地使用 pip 如下所示安裝,可能會(huì)有一些麻煩。
pip install pyopengl
當(dāng)我這樣安裝之后,運(yùn)行 OpenGL 代碼,得到了這樣的錯(cuò)誤信息:
FunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling
原來(lái),pip 默認(rèn)安裝的是32位版本的PyOpenGL,而我的操作系統(tǒng)是64位的。建議點(diǎn)擊這里下載適合自己的版本,直接安裝.whl文件。我是這樣安裝的:
pip install PyOpenGL-3.1.3b2-cp37-cp37m-win_amd64.whl
OpenGL 庫(kù)及函數(shù)簡(jiǎn)介
我第一次接觸 OpenGL 的 GL / GLU / GLUT 的時(shí)候,一下就被這些長(zhǎng)得像孿生兄弟的庫(kù)名字給整懵圈了,要不是內(nèi)心強(qiáng)大,也許就跟 OpenGL 說(shuō)再見(jiàn)了。時(shí)間久了才發(fā)現(xiàn),OpenGL 的庫(kù)及函數(shù)命名規(guī)則非常合理,便于查找、記憶:
OpenGL函數(shù)的命名格式如下:
<庫(kù)前綴><根命令><可選的參數(shù)個(gè)數(shù)><可選的參數(shù)類(lèi)型>
常見(jiàn)的庫(kù)前綴有 gl、glu、glut、aux、wgl、glx、agl 等。庫(kù)前綴表示該函數(shù)屬于 OpenGL 哪一個(gè)開(kāi)發(fā)庫(kù)。從函數(shù)名后面中還可以看出需要多少個(gè)參數(shù)以及參數(shù)的類(lèi)型。I 代表 int 型,f 代表 float 型,d 代表 double 型,u 代表無(wú)符號(hào)整型。例如 glColor3f 表示了該函數(shù)屬于gl庫(kù),參數(shù)是三個(gè)浮點(diǎn)數(shù)。
OpenGL 函數(shù)庫(kù)相關(guān)的 API 有核心庫(kù)(gl)、實(shí)用庫(kù)(glu)、實(shí)用工具庫(kù)(glut)、輔助庫(kù)(aux)、窗口庫(kù)(glx、agl、wgl)和擴(kuò)展函數(shù)庫(kù)等。gl是核心,glu是對(duì)gl的部分封裝。glut是為跨平臺(tái)的OpenGL程序的工具包,比aux功能強(qiáng)大。glx、agl、wgl 是針對(duì)不同窗口系統(tǒng)的函數(shù)。擴(kuò)展函數(shù)庫(kù)是硬件廠(chǎng)商為實(shí)現(xiàn)硬件更新利用OpenGL的擴(kuò)展機(jī)制開(kāi)發(fā)的函數(shù)。本文僅對(duì)常用的四個(gè)庫(kù)做簡(jiǎn)單介紹。
一、OpenGL 核心庫(kù) GL
核心庫(kù)包含有115個(gè)函數(shù),函數(shù)名的前綴為gl。這部分函數(shù)用于常規(guī)的、核心的圖形處理。此函數(shù)由gl.dll來(lái)負(fù)責(zé)解釋執(zhí)行。由于許多函數(shù)可以接收不同數(shù)以下幾類(lèi)。據(jù)類(lèi)型的參數(shù),因此派生出來(lái)的函數(shù)原形多達(dá)300多個(gè)。核心庫(kù)中的函數(shù)主要可以分為以下幾類(lèi)函數(shù):
繪制基本幾何圖元的函數(shù):
glBegain、glEnd、glNormal*、glVertex*
矩陣操作、幾何變換和投影變換的函數(shù):
如矩陣入棧函數(shù)glPushMatrix,矩陣出棧函數(shù)glPopMatrix,裝載矩陣函數(shù)glLoadMatrix,矩陣相乘函數(shù)glMultMatrix,當(dāng)前矩陣函數(shù)glMatrixMode和矩陣標(biāo)準(zhǔn)化函數(shù)glLoadIdentity,幾何變換函數(shù)glTranslate*、glRotate*和glScale*,投影變換函數(shù)glOrtho、glFrustum和視口變換函數(shù)glViewport
顏色、光照和材質(zhì)的函數(shù):
如設(shè)置顏色模式函數(shù)glColor*、glIndex*,設(shè)置光照效果的函數(shù)glLight* 、glLightModel*和設(shè)置材質(zhì)效果函數(shù)glMaterial
顯示列表函數(shù):
主要有創(chuàng)建、結(jié)束、生成、刪除和調(diào)用顯示列表的函數(shù)glNewList、glEndList、glGenLists、glCallList和glDeleteLists
紋理映射函數(shù):
主要有一維紋理函數(shù)glTexImage1D、二維紋理函數(shù)glTexImage2D、設(shè)置紋理參數(shù)、紋理環(huán)境和紋理坐標(biāo)的函數(shù)glTexParameter*、glTexEnv*和glTetCoord*
特殊效果函數(shù):
融合函數(shù)glBlendFunc、反走樣函數(shù)glHint和霧化效果glFog*
光柵化、象素操作函數(shù):
如象素位置glRasterPos*、線(xiàn)型寬度glLineWidth、多邊形繪制模式glPolygonMode,讀取象素glReadPixel、復(fù)制象素glCopyPixel
選擇與反饋函數(shù):
主要有渲染模式glRenderMode、選擇緩沖區(qū)glSelectBuffer和反饋緩沖區(qū)glFeedbackBuffer
曲線(xiàn)與曲面的繪制函數(shù):
生成曲線(xiàn)或曲面的函數(shù)glMap*、glMapGrid*,求值器的函數(shù)glEvalCoord* glEvalMesh*
狀態(tài)設(shè)置與查詢(xún)函數(shù):
glGet*、glEnable、glGetError
二、OpenGL 實(shí)用庫(kù) GLU
包含有43個(gè)函數(shù),函數(shù)名的前綴為glu。OpenGL提供了強(qiáng)大的但是為數(shù)不多的繪圖命令,所有較復(fù)雜的繪圖都必須從點(diǎn)、線(xiàn)、面開(kāi)始。Glu 為了減輕繁重的編程工作,封裝了OpenGL函數(shù),Glu函數(shù)通過(guò)調(diào)用核心庫(kù)的函數(shù),為開(kāi)發(fā)者提供相對(duì)簡(jiǎn)單的用法,實(shí)現(xiàn)一些較為復(fù)雜的操作。此函數(shù)由glu.dll來(lái)負(fù)責(zé)解釋執(zhí)行。OpenGL中的核心庫(kù)和實(shí)用庫(kù)可以在所有的OpenGL平臺(tái)上運(yùn)行。主要包括了以下幾種:
輔助紋理貼圖函數(shù):
gluScaleImage 、gluBuild1Dmipmaps、gluBuild2Dmipmaps
坐標(biāo)轉(zhuǎn)換和投影變換函數(shù):
定義投影方式函數(shù)gluPerspective、gluOrtho2D 、gluLookAt,拾取投影視景體函數(shù)gluPickMatrix,投影矩陣計(jì)算gluProject和gluUnProject
多邊形鑲嵌工具:
gluNewTess、gluDeleteTess、gluTessCallback、gluBeginPolygon、gluTessVertex、gluNextContour、gluEndPolygon
二次曲面繪制工具:
主要有繪制球面、錐面、柱面、圓環(huán)面gluNewQuadric、gluSphere、gluCylinder、gluDisk、gluPartialDisk、gluDeleteQuadric
非均勻有理B樣條繪制工具:
主要用來(lái)定義和繪制Nurbs曲線(xiàn)和曲面,包括gluNewNurbsRenderer、gluNurbsCurve、gluBeginSurface、gluEndSurface、gluBeginCurve、gluNurbsProperty
錯(cuò)誤反饋工具:
獲取出錯(cuò)信息的字符串gluErrorString
三、OpenGL 工具庫(kù) GLUT
包含大約30多個(gè)函數(shù),函數(shù)名前綴為glut。glut是不依賴(lài)于窗口平臺(tái)的OpenGL工具包,由Mark KLilgrad在SGI編寫(xiě)(現(xiàn)在在Nvidia),目的是隱藏不同窗口平臺(tái)API的復(fù)雜度。函數(shù)以glut開(kāi)頭,它們作為aux庫(kù)功能更強(qiáng)的替代品,提供更為復(fù)雜的繪制功能,此函數(shù)由glut.dll來(lái)負(fù)責(zé)解釋執(zhí)行。
由于glut中的窗口管理函數(shù)是不依賴(lài)于運(yùn)行環(huán)境的,因此OpenGL中的工具庫(kù)可以在X-Window、Windows NT、OS/2等系統(tǒng)下運(yùn)行,特別適合于開(kāi)發(fā)不需要復(fù)雜界面的OpenGL示例程序。對(duì)于有經(jīng)驗(yàn)的程序員來(lái)說(shuō),一般先用glut理順3D圖形代碼,然后再集成為完整的應(yīng)用程序。這部分函數(shù)主要包括:
窗口操作函數(shù):
窗口初始化、窗口大小、窗口位置函數(shù)等 glutInit、glutInitDisplayMode、glutInitWindowSize、glutInitWindowPosition
回調(diào)函數(shù):
響應(yīng)刷新消息、鍵盤(pán)消息、鼠標(biāo)消息、定時(shí)器函數(shù) GlutDisplayFunc、glutPostRedisplay、glutReshapeFunc、glutTimerFunc、glutKeyboardFunc、glutMouseFunc
創(chuàng)建復(fù)雜的三維物體:
這些和aux庫(kù)的函數(shù)功能相同。
菜單函數(shù):
創(chuàng)建添加菜單的函數(shù) GlutCreateMenu、glutSetMenu、glutAddMenuEntry、glutAddSubMenu 和 glutAttachMenu
程序運(yùn)行函數(shù):
glutMainLoop
四、Windows 專(zhuān)用庫(kù) WGL
針對(duì)Windows平臺(tái)的擴(kuò)展,包含有16個(gè)函數(shù),函數(shù)名前綴為wgl。這部分函數(shù)主要用于連接OpenGL和Windows ,以彌補(bǔ)OpenGL在文本方面的不足。Windows專(zhuān)用庫(kù)只能用于Windows環(huán)境中。這類(lèi)函數(shù)主要包括以下幾類(lèi):
繪圖上下文相關(guān)函數(shù):
wglCreateContext、wglDeleteContext、wglGetCurrentContent、wglGetCurrentDC、wglDeleteContent
文字和文本處理函數(shù):
wglUseFontBitmaps、wglUseFontOutlines
覆蓋層、地層和主平面層處理函數(shù):
wglCopyContext、wglCreateLayerPlane、wglDescribeLayerPlane、wglReakizeLayerPlatte
其他函數(shù):
wglShareLists、wglGetProcAddress
開(kāi)始 OpenGL 的奇幻之旅
一、OpenGL 基本圖形的繪制
設(shè)置顏色
設(shè)置顏色的函數(shù)有幾十個(gè),都是以 glColor 開(kāi)頭,后面跟著參數(shù)個(gè)數(shù)和參數(shù)類(lèi)型。參數(shù)可以是 0 到 255 之間的無(wú)符號(hào)整數(shù),也可以是 0 到 1 之間的浮點(diǎn)數(shù)。三個(gè)參數(shù)分別表示 RGB 分量,第四個(gè)參數(shù)表示透明度(其實(shí)叫不透明度更恰當(dāng))。以下最常用的兩個(gè)設(shè)置顏色的方法:
glColor3f(1.0,0.0,0.0) # 設(shè)置當(dāng)前顏色為紅色
glColor4f(0.0,1.0,1.0,1.0) # 設(shè)置當(dāng)前顏色為青色,不透明度
glColor3ub(0, 0, 255) # 設(shè)置當(dāng)前顏色為藍(lán)色
glColor 也支持將三個(gè)或四個(gè)參數(shù)以向量方式傳遞,例如:
glColor3fv([0.0,1.0,0.0]) # 設(shè)置當(dāng)前顏色為綠色
特別提示:OpenGL 是使用狀態(tài)機(jī)模式,顏色是一個(gè)狀態(tài)變量,設(shè)置顏色就是改變這個(gè)狀態(tài)變量并一直生效,直到再次調(diào)用設(shè)置顏色的函數(shù)。除了顏色,OpenGL 還有很多的狀態(tài)變量或模式。在任何時(shí)間,都可以查詢(xún)每個(gè)狀態(tài)變量的當(dāng)前值,還可以用 glPushAttrib 或 glPushClientAttrib 把狀態(tài)變量的集合保存起來(lái),必要的時(shí)候,再用 glPopAttrib 或 glPopClientAttrib 恢復(fù)狀態(tài)變量。
設(shè)置頂點(diǎn)
頂點(diǎn)(vertex)是 OpengGL 中非常重要的概念,描述線(xiàn)段、多邊形都離不開(kāi)頂點(diǎn)。和設(shè)置顏色類(lèi)似,設(shè)置頂點(diǎn)的函數(shù)也有幾十個(gè),都是以 glVertex 開(kāi)頭,后面跟著參數(shù)個(gè)數(shù)和參數(shù)類(lèi)型,同樣也支持將多個(gè)以向量方式傳遞。兩個(gè)參數(shù)的話(huà),分別表示 xy 坐標(biāo),三個(gè)參數(shù)則分別表示 xyz 坐標(biāo)。如有第四個(gè)參數(shù),則表示該點(diǎn)的齊次坐標(biāo) w;否則,默認(rèn) w=1。至于什么是齊次坐標(biāo),顯然超出了初中數(shù)學(xué)的范疇,在此不做探討。
glVertex2f(1.0,0.5) # xoy平面上的點(diǎn),z=0
glVertex3f(0.5,1.0,0.0) # 三維空間中的點(diǎn)
繪制基本圖形
僅僅設(shè)置顏色和頂點(diǎn),并不能畫(huà)出來(lái)什么。我們可以在任何時(shí)候改變顏色,但所有的頂點(diǎn)設(shè)置,都必須包含在 glBegin 和 glEnd 之間,而 glBegin 的參數(shù)則指定了將這些頂點(diǎn)畫(huà)成什么。以下是 glBegin 可能的參數(shù)選項(xiàng):
二、第一個(gè) OpenGL 程序
通常,我們使用工具庫(kù)(GLUT)創(chuàng)建 OpenGL 應(yīng)用程序。為啥不用 GL 或者 GLU 庫(kù)呢?畫(huà)畫(huà)之前總得先有一塊畫(huà)布吧,不能直接拿起畫(huà)筆就開(kāi)畫(huà)。前文說(shuō)過(guò),工具庫(kù)主要提供窗口相關(guān)的函數(shù),有了窗口,就相當(dāng)于有了畫(huà)布,而核心庫(kù)和實(shí)用庫(kù),就好比各式各樣的畫(huà)筆、顏料。使用工具庫(kù)(GLUT)創(chuàng)建 OpenGL 應(yīng)用程序只需要四步(當(dāng)然,前提是你需要先準(zhǔn)備好繪圖函數(shù),并給它取一個(gè)合適的名字):
初始化glut庫(kù)
創(chuàng)建glut窗口
注冊(cè)繪圖的回調(diào)函數(shù)
進(jìn)入glut主循環(huán)
OK,鋪墊了這么多之后,我們終于開(kāi)始第一個(gè) OpenGL 應(yīng)用程序了:繪制三維空間的世界坐標(biāo)系,在坐標(biāo)原點(diǎn)的后方(z軸的負(fù)半?yún)^(qū))畫(huà)一個(gè)三角形。代碼如下:
# -*- coding: utf-8 -*-
# -------------------------------------------
# quidam_01.py 三維空間的世界坐標(biāo)系和三角形
# -------------------------------------------
from OpenGL.GL import *
from OpenGL.GLUT import *
def draw:
# ---------------------------------------------------------------
glBegin(GL_LINES) # 開(kāi)始繪制線(xiàn)段(世界坐標(biāo)系)
# 以紅色繪制x軸
glColor4f(1.0, 0.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為紅色不透明
glVertex3f(-0.8, 0.0, 0.0) # 設(shè)置x軸頂點(diǎn)(x軸負(fù)方向)
glVertex3f(0.8, 0.0, 0.0) # 設(shè)置x軸頂點(diǎn)(x軸正方向)
# 以綠色繪制y軸
glColor4f(0.0, 1.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為綠色不透明
glVertex3f(0.0, -0.8, 0.0) # 設(shè)置y軸頂點(diǎn)(y軸負(fù)方向)
glVertex3f(0.0, 0.8, 0.0) # 設(shè)置y軸頂點(diǎn)(y軸正方向)
# 以藍(lán)色繪制z軸
glColor4f(0.0, 0.0, 1.0, 1.0) # 設(shè)置當(dāng)前顏色為藍(lán)色不透明
glVertex3f(0.0, 0.0, -0.8) # 設(shè)置z軸頂點(diǎn)(z軸負(fù)方向)
glVertex3f(0.0, 0.0, 0.8) # 設(shè)置z軸頂點(diǎn)(z軸正方向)
glEnd # 結(jié)束繪制線(xiàn)段
# ---------------------------------------------------------------
glBegin(GL_TRIANGLES) # 開(kāi)始繪制三角形(z軸負(fù)半?yún)^(qū))
glColor4f(1.0, 0.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為紅色不透明
glVertex3f(-0.5, -0.366, -0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 1.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為綠色不透明
glVertex3f(0.5, -0.366, -0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 0.0, 1.0, 1.0) # 設(shè)置當(dāng)前顏色為藍(lán)色不透明
glVertex3f(0.0, 0.5, -0.5) # 設(shè)置三角形頂點(diǎn)
glEnd
# 結(jié)束繪制三角形
# ---------------------------------------------------------------
glFlush # 清空緩沖區(qū),將指令送往硬件立即執(zhí)行
if __name__ == "__main__":
glutInit # 1. 初始化glut庫(kù)
glutCreateWindow('Quidam Of OpenGL') # 2. 創(chuàng)建glut窗口
glutDisplayFunc(draw) # 3. 注冊(cè)回調(diào)函數(shù)draw
glutMainLoop # 4. 進(jìn)入glut主循環(huán)
運(yùn)行代碼,我這里顯示結(jié)果如下面左圖所示。如果嘗試運(yùn)行這段代碼出錯(cuò)的話(huà),我猜應(yīng)該是 PyOpenGL 安裝出現(xiàn)了問(wèn)題,建議返回到前面重讀 PyOpenGL 的安裝。
短暫的激動(dòng)之后,你可能會(huì)嘗試畫(huà)一些其他的線(xiàn)段,變換顏色或者透明度,甚至繪制多邊形。很快你會(huì)發(fā)現(xiàn),我們的第一個(gè)程序有很多問(wèn)題,比如:
窗口的標(biāo)題不能使用中文,否則會(huì)顯示亂碼
窗口的初始大小和位置無(wú)法改變
改變窗口的寬高比,三角形寬高比也會(huì)改變(如上面右圖所示)
三角形不應(yīng)該遮擋坐標(biāo)軸
改變顏色的透明度無(wú)效
不能縮放旋轉(zhuǎn)
沒(méi)關(guān)系,除了第1個(gè)問(wèn)題我不知道怎么解決(貌似無(wú)解),其他問(wèn)題都不是事兒。和我們的代碼相比,一個(gè)真正實(shí)用的 OpenGL 程序,還有許多工作要做:
設(shè)置初始顯示模式
初始化畫(huà)布
繪圖函數(shù)里面需要增加:清除屏幕及深度緩存、投影設(shè)置、模型試圖設(shè)置
綁定鼠標(biāo)鍵盤(pán)的事件函數(shù)
三、設(shè)置初始顯示模式
初始化 glut 庫(kù)的時(shí)候,我們一般都要用 glutInitDisplayMode 來(lái)設(shè)置初始的顯示模式,它的參數(shù)可以是下表中參數(shù)的組合。
使用雙緩存窗口,可以避免重繪時(shí)產(chǎn)生抖動(dòng)的感覺(jué)。我一般選擇 GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH 作為參數(shù)來(lái)設(shè)置初始的顯示模式。
四、初始化畫(huà)布
開(kāi)始繪圖之前,需要對(duì)畫(huà)布做一些初始化工作,這些工作只需要做一次。比如:
glClearColor(0.0, 0.0, 0.0, 1.0) # 設(shè)置畫(huà)布背景色。注意:這里必須是4個(gè)參數(shù)
glEnable(GL_DEPTH_TEST) # 開(kāi)啟深度測(cè)試,實(shí)現(xiàn)遮擋關(guān)系
glDepthFunc(GL_LEQUAL) # 設(shè)置深度測(cè)試函數(shù)(GL_LEQUAL只是選項(xiàng)之一)
如有必要,還可以開(kāi)啟失真校正(反走樣)、開(kāi)啟表面剔除等。
五、清除屏幕及深度緩存
每次重繪之前,需要先清除屏幕及深度緩存。這項(xiàng)操作一般放在繪圖函數(shù)的開(kāi)頭。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
六、設(shè)置投影
投影設(shè)置也是每次重繪都需要的步驟之一。glOrtho 用來(lái)設(shè)置平行投影,glFrustum 用來(lái)設(shè)置透視投影。這兩個(gè)函數(shù)的參數(shù)相同,都是視景體的 left / right / bottom / top / near / far 六個(gè)面。
視景體的 left / right / bottom / top 四個(gè)面圍成的矩形,就是視口。near 就是投影面,其值是投影面距離視點(diǎn)的距離,far 是視景體的后截面,其值是后截面距離視點(diǎn)的距離。far 和 near 的差值,就是視景體的深度。視點(diǎn)和視景體的相對(duì)位置關(guān)系是固定的,視點(diǎn)移動(dòng)時(shí),視景體也隨之移動(dòng)。
我個(gè)人認(rèn)為,視景體是 OpengGL 最重要、最核心的概念,它和視口、視點(diǎn)、投影面、縮放、漫游等概念密切關(guān)聯(lián)。只有正確理解了視景體,才能正確設(shè)置它的六個(gè)參數(shù),才能呈現(xiàn)出我們期望的效果。
為了在窗口寬高比改變時(shí),繪制的對(duì)象仍然保持固定的寬高比,一般在做投影變換時(shí),需要根據(jù)窗口的寬高比適當(dāng)調(diào)整視景體的 left / right 或者 bottom / top 參數(shù)。
假設(shè) view 是視景體,width 和 height 是窗口的寬度和高度,在投影變換之前,需要先聲明是對(duì)投影矩陣的操作,并將投影矩陣單位化:
glMatrixMode(GL_PROJECTION)
glLoadIdentity
if width > height:
k = width / height
glFrustum(view [0]*k, view [1]*k, view [2], view [3], view [4], view [5])
else:
k = height / width
glFrustum(view [0], view [1], view [2]*k, view [3]*k, view [4], view [5])
七、設(shè)置視點(diǎn)
視點(diǎn)是和視景體關(guān)聯(lián)的概念。設(shè)置視點(diǎn)需要考慮眼睛在哪兒、看哪兒、頭頂朝哪兒,分別對(duì)應(yīng)著eye、lookat 和 eye_up 三個(gè)向量。
gluLookAt(
eye[0], eye[1], eye[2],
look_at[0], look_at[1], look_at[2],
eye_up[0], eye_up[1], eye_up[2]
)
八、設(shè)置視口
視口也是和視景體關(guān)聯(lián)的概念,相對(duì)簡(jiǎn)單一點(diǎn)。
glViewport(0, 0, width, height)
九、設(shè)置模型視圖
模型平移、旋轉(zhuǎn)、縮放等幾何變換,需要切換到模型矩陣:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity
glScale(1.0, 1.0, 1.0)
十、捕捉鼠標(biāo)事件、鍵盤(pán)事件和窗口事件
GLUT 庫(kù)提供了幾個(gè)函數(shù)幫我們捕捉鼠標(biāo)事件、鍵盤(pán)事件和窗口事件:
glutMouseFunc
該函數(shù)捕捉鼠標(biāo)點(diǎn)擊和滾輪操作,返回4個(gè)參數(shù)給被綁定的事件函數(shù):鍵(左鍵/右鍵/中鍵/滾輪上/滾輪下)、狀態(tài)(1/0)、x坐標(biāo)、y坐標(biāo)
glutMotionFunc
該函數(shù)捕捉有一個(gè)鼠標(biāo)鍵被按下時(shí)的鼠標(biāo)移動(dòng)給被綁定的事件函數(shù),返回2個(gè)參數(shù):x坐標(biāo)、y坐標(biāo)
glutPassiveMotionFunc
該函數(shù)捕捉鼠標(biāo)移動(dòng),返回2個(gè)參數(shù)給被綁定的事件函數(shù):x坐標(biāo)、y坐標(biāo)
glutEntryFunc
該函數(shù)捕捉鼠標(biāo)離開(kāi)或進(jìn)入窗口區(qū)域,返回1個(gè)參數(shù)給被綁定的事件函數(shù):GLUT_LEFT 或者 GLUT_ENTERED
glutKeyboardFunc(keydown)
該函數(shù)捕捉鍵盤(pán)按鍵被按下,返回3個(gè)參數(shù)給被綁定的事件函數(shù):被按下的鍵,x坐標(biāo)、y坐標(biāo)
glutReshapeFunc
該函數(shù)捕捉窗口被改變大小,返回2個(gè)參數(shù)給被綁定的事件函數(shù):窗口寬度、窗口高度
如果我們需要捕捉這些事件,只需要定義事件函數(shù),注冊(cè)相應(yīng)的函數(shù)就行:
def reshape(width, height):
pass
def mouseclick(button, state, x, y):
pass
def mousemotion(x, y):
pass
def keydown(key, x, y):
pass
glutReshapeFunc(reshape) # 注冊(cè)響應(yīng)窗口改變的函數(shù)reshape
glutMouseFunc(mouseclick) # 注冊(cè)響應(yīng)鼠標(biāo)點(diǎn)擊的函數(shù)mouseclick
glutMotionFunc(mousemotion) # 注冊(cè)響應(yīng)鼠標(biāo)拖拽的函數(shù)mousemotion
glutKeyboardFunc(keydown) # 注冊(cè)鍵盤(pán)輸入的函數(shù)keydown
十一、綜合應(yīng)用
是時(shí)候把我們上面講的這些東西完整的演示一下了。下面的代碼還是畫(huà)了世界坐標(biāo)系,并在原點(diǎn)前后各畫(huà)了一個(gè)三角形。鼠標(biāo)可以拖拽視點(diǎn)繞參考點(diǎn)旋轉(zhuǎn)(二者距離保持不變),滾輪可以縮放模型。
敲擊退格鍵或回車(chē)鍵可以讓視點(diǎn)遠(yuǎn)離或接近參考點(diǎn)。敲擊 x/y/z 可以減小參考點(diǎn)對(duì)應(yīng)的坐標(biāo)值,敲擊 X/Y/Z 可以增大參考點(diǎn)對(duì)應(yīng)的坐標(biāo)值。敲擊空格鍵可以切換投影模式。
上圖左是平行投影模式的顯示效果,上圖右是透視投影模式的顯示效果。代碼如下:
# -*- coding: utf-8 -*-
# -------------------------------------------
# quidam_02.py 旋轉(zhuǎn)、縮放、改變視點(diǎn)和參考點(diǎn)
# -------------------------------------------
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import numpy as np
IS_PERSPECTIVE = True # 透視投影
VIEW = np.array([-0.8, 0.8, -0.8, 0.8, 1.0, 20.0]) # 視景體的left/right/bottom/top/near/far六個(gè)面
SCALE_K = np.array([1.0, 1.0, 1.0]) # 模型縮放比例
EYE = np.array([0.0, 0.0, 2.0]) # 眼睛的位置(默認(rèn)z軸的正方向)
LOOK_AT = np.array([0.0, 0.0, 0.0]) # 瞄準(zhǔn)方向的參考點(diǎn)(默認(rèn)在坐標(biāo)原點(diǎn))
EYE_UP = np.array([0.0, 1.0, 0.0]) # 定義對(duì)觀(guān)察者而言的上方(默認(rèn)y軸的正方向)
WIN_W, WIN_H = 640, 480 # 保存窗口寬度和高度的變量
LEFT_IS_DOWNED = False # 鼠標(biāo)左鍵被按下
MOUSE_X, MOUSE_Y = 0, 0 # 考察鼠標(biāo)位移量時(shí)保存的起始位置
def getposture:
global EYE, LOOK_AT
dist = np.sqrt(np.power((EYE-LOOK_AT), 2).sum)
if dist > 0:
phi = np.arcsin((EYE[1]-LOOK_AT[1])/dist)
theta = np.arcsin((EYE[0]-LOOK_AT[0])/(dist*np.cos(phi)))
else:
phi = 0.0
theta = 0.0
return dist, phi, theta
DIST, PHI, THETA = getposture # 眼睛與觀(guān)察目標(biāo)之間的距離、仰角、方位角
def init:
glClearColor(0.0, 0.0, 0.0, 1.0) # 設(shè)置畫(huà)布背景色。注意:這里必須是4個(gè)參數(shù)
glEnable(GL_DEPTH_TEST) # 開(kāi)啟深度測(cè)試,實(shí)現(xiàn)遮擋關(guān)系
glDepthFunc(GL_LEQUAL) # 設(shè)置深度測(cè)試函數(shù)(GL_LEQUAL只是選項(xiàng)之一)
def draw:
global IS_PERSPECTIVE, VIEW
global EYE, LOOK_AT, EYE_UP
global SCALE_K
global WIN_W, WIN_H
# 清除屏幕及深度緩存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# 設(shè)置投影(透視投影)
glMatrixMode(GL_PROJECTION)
glLoadIdentity
if WIN_W > WIN_H:
if IS_PERSPECTIVE:
glFrustum(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
else:
glOrtho(VIEW[0]*WIN_W/WIN_H, VIEW[1]*WIN_W/WIN_H, VIEW[2], VIEW[3], VIEW[4], VIEW[5])
else:
if IS_PERSPECTIVE:
glFrustum(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
else:
glOrtho(VIEW[0], VIEW[1], VIEW[2]*WIN_H/WIN_W, VIEW[3]*WIN_H/WIN_W, VIEW[4], VIEW[5])
# 設(shè)置模型視圖
glMatrixMode(GL_MODELVIEW)
glLoadIdentity
# 幾何變換
glScale(SCALE_K[0], SCALE_K[1], SCALE_K[2])
# 設(shè)置視點(diǎn)
gluLookAt(
EYE[0], EYE[1], EYE[2],
LOOK_AT[0], LOOK_AT[1], LOOK_AT[2],
EYE_UP[0], EYE_UP[1], EYE_UP[2]
)
# 設(shè)置視口
glViewport(0, 0, WIN_W, WIN_H)
# ---------------------------------------------------------------
glBegin(GL_LINES) # 開(kāi)始繪制線(xiàn)段(世界坐標(biāo)系)
# 以紅色繪制x軸
glColor4f(1.0, 0.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為紅色不透明
glVertex3f(-0.8, 0.0, 0.0) # 設(shè)置x軸頂點(diǎn)(x軸負(fù)方向)
glVertex3f(0.8, 0.0, 0.0) # 設(shè)置x軸頂點(diǎn)(x軸正方向)
# 以綠色繪制y軸
glColor4f(0.0, 1.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為綠色不透明
glVertex3f(0.0, -0.8, 0.0) # 設(shè)置y軸頂點(diǎn)(y軸負(fù)方向)
glVertex3f(0.0, 0.8, 0.0) # 設(shè)置y軸頂點(diǎn)(y軸正方向)
# 以藍(lán)色繪制z軸
glColor4f(0.0, 0.0, 1.0, 1.0) # 設(shè)置當(dāng)前顏色為藍(lán)色不透明
glVertex3f(0.0, 0.0, -0.8) # 設(shè)置z軸頂點(diǎn)(z軸負(fù)方向)
glVertex3f(0.0, 0.0, 0.8) # 設(shè)置z軸頂點(diǎn)(z軸正方向)
glEnd # 結(jié)束繪制線(xiàn)段
# ---------------------------------------------------------------
glBegin(GL_TRIANGLES) # 開(kāi)始繪制三角形(z軸負(fù)半?yún)^(qū))
glColor4f(1.0, 0.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為紅色不透明
glVertex3f(-0.5, -0.366, -0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 1.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為綠色不透明
glVertex3f(0.5, -0.366, -0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 0.0, 1.0, 1.0) # 設(shè)置當(dāng)前顏色為藍(lán)色不透明
glVertex3f(0.0, 0.5, -0.5) # 設(shè)置三角形頂點(diǎn)
glEnd # 結(jié)束繪制三角形
# ---------------------------------------------------------------
glBegin(GL_TRIANGLES) # 開(kāi)始繪制三角形(z軸正半?yún)^(qū))
glColor4f(1.0, 0.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為紅色不透明
glVertex3f(-0.5, 0.5, 0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 1.0, 0.0, 1.0) # 設(shè)置當(dāng)前顏色為綠色不透明
glVertex3f(0.5, 0.5, 0.5) # 設(shè)置三角形頂點(diǎn)
glColor4f(0.0, 0.0, 1.0, 1.0) # 設(shè)置當(dāng)前顏色為藍(lán)色不透明
glVertex3f(0.0, -0.366, 0.5) # 設(shè)置三角形頂點(diǎn)
glEnd # 結(jié)束繪制三角形
# ---------------------------------------------------------------
glutSwapBuffers # 切換緩沖區(qū),以顯示繪制內(nèi)容
def reshape(width, height):
global WIN_W, WIN_H
WIN_W, WIN_H = width, height
glutPostRedisplay
def mouseclick(button, state, x, y):
global SCALE_K
global LEFT_IS_DOWNED
global MOUSE_X, MOUSE_Y
MOUSE_X, MOUSE_Y = x, y
if button == GLUT_LEFT_BUTTON:
LEFT_IS_DOWNED = state==GLUT_DOWN
elif button == 3:
SCALE_K *= 1.05
glutPostRedisplay
elif button == 4:
SCALE_K *= 0.95
glutPostRedisplay
def mousemotion(x, y):
global LEFT_IS_DOWNED
global EYE, EYE_UP
global MOUSE_X, MOUSE_Y
global DIST, PHI, THETA
global WIN_W, WIN_H
if LEFT_IS_DOWNED:
dx = MOUSE_X - x
dy = y - MOUSE_Y
MOUSE_X, MOUSE_Y = x, y
PHI += 2*np.pi*dy/WIN_H
PHI %= 2*np.pi
THETA += 2*np.pi*dx/WIN_W
THETA %= 2*np.pi
r = DIST*np.cos(PHI)
EYE[1] = DIST*np.sin(PHI)
EYE[0] = r*np.sin(THETA)
EYE[2] = r*np.cos(THETA)
if 0.5*np.pi < PHI < 1.5*np.pi:
EYE_UP[1] = -1.0
else:
EYE_UP[1] = 1.0
glutPostRedisplay
def keydown(key, x, y):
global DIST, PHI, THETA
global EYE, LOOK_AT, EYE_UP
global IS_PERSPECTIVE, VIEW
if key in [b'x', b'X', b'y', b'Y', b'z', b'Z']:
if key == b'x': # 瞄準(zhǔn)參考點(diǎn) x 減小
LOOK_AT[0] -= 0.01
elif key == b'X': # 瞄準(zhǔn)參考 x 增大
LOOK_AT[0] += 0.01
elif key == b'y': # 瞄準(zhǔn)參考點(diǎn) y 減小
LOOK_AT[1] -= 0.01
elif key == b'Y': # 瞄準(zhǔn)參考點(diǎn) y 增大
LOOK_AT[1] += 0.01
elif key == b'z': # 瞄準(zhǔn)參考點(diǎn) z 減小
LOOK_AT[2] -= 0.01
elif key == b'Z': # 瞄準(zhǔn)參考點(diǎn) z 增大
LOOK_AT[2] += 0.01
DIST, PHI, THETA = getposture
glutPostRedisplay
elif key == b'\r': # 回車(chē)鍵,視點(diǎn)前進(jìn)
EYE = LOOK_AT + (EYE - LOOK_AT) * 0.9
DIST, PHI, THETA = getposture
glutPostRedisplay
elif key == b'\x08': # 退格鍵,視點(diǎn)后退
EYE = LOOK_AT + (EYE - LOOK_AT) * 1.1
DIST, PHI, THETA = getposture
glutPostRedisplay
elif key == b' ': # 空格鍵,切換投影模式
IS_PERSPECTIVE = not IS_PERSPECTIVE
glutPostRedisplay
if __name__ == "__main__":
glutInit
displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH
glutInitDisplayMode(displayMode)
glutInitWindowSize(WIN_W, WIN_H)
glutInitWindowPosition(300, 200)
glutCreateWindow('Quidam Of OpenGL')
init # 初始化畫(huà)布
glutDisplayFunc(draw) # 注冊(cè)回調(diào)函數(shù)draw
glutReshapeFunc(reshape) # 注冊(cè)響應(yīng)窗口改變的函數(shù)reshape
glutMouseFunc(mouseclick) # 注冊(cè)響應(yīng)鼠標(biāo)點(diǎn)擊的函數(shù)mouseclick
glutMotionFunc(mousemotion) # 注冊(cè)響應(yīng)鼠標(biāo)拖拽的函數(shù)mousemotion
glutKeyboardFunc(keydown) # 注冊(cè)鍵盤(pán)輸入的函數(shù)keydown
glutMainLoop # 進(jìn)入glut主循環(huán)
十二、小結(jié)
雖然還有很多領(lǐng)域需要我們繼續(xù)探索,比如燈光、材質(zhì)、霧化、拾取等,但那不是奇幻之旅的目標(biāo)。奇幻之旅僅僅是幫助讀者建立 OpenGL 的基本概念。至此,我們基本完成了任務(wù)。
加速渲染
實(shí)際應(yīng)用 OpenGL 繪制三維圖像時(shí),往往需要處理數(shù)以萬(wàn)計(jì)的頂點(diǎn),有時(shí)甚至是百萬(wàn)級(jí)、千萬(wàn)級(jí)。我們通常不會(huì)在繪制函數(shù)里面?zhèn)魉瓦@些數(shù)據(jù),而是在繪制之前,將這些數(shù)據(jù)提前傳送到GPU。繪制函數(shù)每次繪制時(shí),只需要從GPU的緩存中取出數(shù)據(jù)即可,極大地提高了效率。這個(gè)機(jī)制地實(shí)現(xiàn),依賴(lài)于頂點(diǎn)緩沖區(qū)對(duì)象(Vertex Buffer Object),簡(jiǎn)稱(chēng)VBO。
盡管 VBO 是顯卡的擴(kuò)展,其實(shí)沒(méi)有用到GPU運(yùn)算,也就是說(shuō) VBO 不用寫(xiě)著色語(yǔ)言,直接用opengl函數(shù)就可以調(diào)用,主要目的是用于加快渲染的速。
VBO 將頂點(diǎn)信息放到 GPU 中,GPU 在渲染時(shí)去緩存中取數(shù)據(jù),二者中間的橋梁是 GL-Context。GL-Context 整個(gè)程序一般只有一個(gè),所以如果一個(gè)渲染流程里有兩份不同的繪制代碼,GL-context 就負(fù)責(zé)在他們之間進(jìn)行切換。這也是為什么要在渲染過(guò)程中,在每份繪制代碼之中會(huì)有 glBindbuffer、glEnableVertexAttribArray、glVertexAttribPointer。如果把這些都放到初始化時(shí)候完成,使用一種結(jié)構(gòu)記錄該次繪制所需要的所有 VBO 所需信息,把它保存到 VBO特定位置,繪制的時(shí)候直接在這個(gè)位置取信息繪制,會(huì)簡(jiǎn)化渲染流程、提升渲染速度。這就是 VAO 概念產(chǎn)生的初衷。
VAO 的全名是 Vertex Array Object,首先,它不是 Buffer-Object,所以不用作存儲(chǔ)數(shù)據(jù);其次,它針對(duì)“頂點(diǎn)”而言,也就是說(shuō)它跟“頂點(diǎn)的繪制”息息相關(guān)。VAO 記錄的是一次繪制中所需要的信息,這包括“數(shù)據(jù)在哪里 glBindBuffer”、“數(shù)據(jù)的格式是怎么樣的 glVertexAttribPointer”、shader-attribute 的 location 的啟用 glEnableVertexAttribArray。
根據(jù)我查到的資料,幾乎所有的顯卡都支持 VBO,但不是所有的顯卡都支持 VAO,而 VAO 僅僅是優(yōu)化了 VBO 的使用方法,對(duì)于加速并沒(méi)有實(shí)質(zhì)性的影響,因此本文只討論 VBO 技術(shù)。
一、創(chuàng)建頂點(diǎn)緩沖區(qū)對(duì)象(VBO)
假定畫(huà)一個(gè)六面體,頂點(diǎn)是這樣的:
# -*- coding: utf-8 -*-
# 六面體數(shù)據(jù)
# ------------------------------------------------------
# v4----- v5
# /| /|
# v0------v1|
# | | | |
# | v7----|-v6
# |/ |/
# v3------v2
# 頂點(diǎn)集
vertices = np.array([
-0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, # v0-v1-v2-v3
-0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5 # v4-v5-v6-v7
], dtype=np.float32)
# 索引集
indices = np.array([
0, 1, 2, 3, # v0-v1-v2-v3 (front)
4, 5, 1, 0, # v4-v5-v1-v0 (top)
3, 2, 6, 7, # v3-v2-v6-v7 (bottom)
5, 4, 7, 6, # v5-v4-v7-v6 (back)
1, 5, 6, 2, # v1-v5-v6-v2 (right)
4, 0, 3, 7 # v4-v0-v3-v7 (left)
], dtype=np.int)
在GPU上創(chuàng)建VBO如下:
from OpenGL.arrays import vbo
vbo_vertices = vbo.VBO(vertices)
vbo_indices = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
創(chuàng)建 頂點(diǎn) VBO 時(shí),默認(rèn) target=GL_ARRAY_BUFFER, 而創(chuàng)建索引 VBO 時(shí),target=GL_ELEMENT_ARRAY_BUFFER,因?yàn)轫旤c(diǎn)的數(shù)據(jù)類(lèi)型是 np.float32,索引的數(shù)據(jù)類(lèi)型是np.int。
在VBO保存的頂點(diǎn)數(shù)據(jù)集,除了頂點(diǎn)信息外,還可以包含顏色、法線(xiàn)、紋理等數(shù)據(jù),這就是頂點(diǎn)混合數(shù)組的概念。假定我們?cè)谏厦娴捻旤c(diǎn)集中增加每個(gè)頂點(diǎn)的顏色,則可以寫(xiě)成這樣:
vertices = np.array([
0.3, 0.6, 0.9, -0.35, 0.35, 0.35, # c0-v0
0.6, 0.9, 0.3, 0.35, 0.35, 0.35, # c1-v1
0.9, 0.3, 0.6, 0.35, -0.35, 0.35, # c2-v2
0.3, 0.9, 0.6, -0.35, -0.35, 0.35, # c3-v3
0.6, 0.3, 0.9, -0.35, 0.35, -0.35, # c4-v4
0.9, 0.6, 0.3, 0.35, 0.35, -0.35, # c5-v5
0.3, 0.9, 0.9, 0.35, -0.35, -0.35, # c6-v6
0.9, 0.9, 0.3, -0.35, -0.35, -0.35 # c7-v7
], dtype=np.float32)
二、分離頂點(diǎn)混合數(shù)組
使用 glInterleavedArrays 函數(shù)可以從頂點(diǎn)混合數(shù)組中分離頂點(diǎn)、顏色、法線(xiàn)和紋理。比如,對(duì)只包含頂點(diǎn)信息的頂點(diǎn)混合數(shù)組:
vbo_indices.bind
glInterleavedArrays(GL_V3F, 0, None)
如果頂點(diǎn)混合數(shù)組包含了顏色和頂點(diǎn)信息:
vbo_indices.bind
glInterleavedArrays(GL_C3F_V3F, 0, None)
glInterleavedArrays 函數(shù)第一個(gè)參數(shù)總共有14個(gè)選項(xiàng),分別是:
GL_V2F
GL_V3F
GL_C4UB_V2F
GL_C4UB_V3F
GL_C3F_V3F
GL_N3F_V3F
GL_C4F_N3F_V3F
GL_T2F_V3F
GL_T4F_V4F
GL_T2F_C4UB_V3F
GL_T2F_C3F_V3F
GL_T2F_N3F_V3F
GL_T2F_C4F_N3F_V3F
GL_T4F_C4F_N3F_V4F
三、使用頂點(diǎn)緩沖區(qū)對(duì)象(VBO)
使用glDrawElements 等函數(shù)繪制前,需要先綁定頂點(diǎn)數(shù)據(jù)集和索引數(shù)據(jù)集,然后使用glInterleavedArrays 分理出頂點(diǎn)、顏色、法線(xiàn)等數(shù)據(jù)。
vbo_indices.bind
glInterleavedArrays(GL_V3F, 0, None)
vbo_indices.bind
glDrawElements(GL_QUADS, int(vbo_indices .size/4), GL_UNSIGNED_INT, None)
vbo_indices.unbind
vbo_indices.unbind
致謝:
寫(xiě)作過(guò)程中,我參考了很多資料,包括紙質(zhì)書(shū)籍和網(wǎng)頁(yè),列寫(xiě)于此,一并致謝!
《OpenGL編程精粹》楊柏林 陳根浪 徐靜 編著
Opengl開(kāi)發(fā)庫(kù)介紹
OpenGL的API函數(shù)使用手冊(cè)
glut處理鼠標(biāo)事件
Learn OpenGL
原文:https://blog.csdn.net/xufive/article/details/86565130
聲明:本文系CSDN博客原創(chuàng)文章,轉(zhuǎn)載請(qǐng)聯(lián)系原作者。
【End】
“只講技術(shù),拒絕空談!”2019 AI開(kāi)發(fā)者大會(huì)將于9月6日-7日在北京舉行,這一屆AI開(kāi)發(fā)者大會(huì)有哪些亮點(diǎn)?一線(xiàn)公司的大牛們都在關(guān)注什么?AI行業(yè)的風(fēng)向是什么?2019 AI開(kāi)發(fā)者大會(huì),傾聽(tīng)大牛分享,聚焦技術(shù)實(shí)踐,和萬(wàn)千開(kāi)發(fā)者共成長(zhǎng)。
目前,大會(huì)盲訂票限量發(fā)售中~掃碼購(gòu)票,領(lǐng)先一步!
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。