├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── LICENSE-CC-BY-SA ├── README.adoc ├── animations ├── body │ ├── 0-static.anim │ ├── 0-static.bis │ ├── 1-punch.anim │ ├── 2-two-punches.anim │ ├── 3-spacium.anim │ ├── 3-spacium.bis │ └── 4-zeperion.anim ├── dynamic │ └── .PLACEHOLDER └── static │ ├── 0-加载图像.png │ ├── 1-wink.png │ ├── 2-不开心.png │ ├── 3-寄了.png │ ├── 4-先辈恶臭.png │ ├── 5-流汗黄豆.png │ └── 6-蓝屏.png ├── attachments └── .PLACEHOLDER ├── blobs ├── come-to-dd-me.jpg ├── designs │ ├── README.adoc │ ├── 设计方案B.png │ ├── 设计方案B.psd │ ├── 设计案C1.jpg │ └── 设计案C2.jpg └── render-output.jpg ├── config.ini ├── extra ├── animations │ ├── Taunter │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── Taunter.cc │ │ └── taunter.qrc │ └── TypeWriter │ │ ├── TypeWriter.cc │ │ ├── TypeWriterControl.cc │ │ └── TypeWriterControl.h ├── attachments │ └── Emitter │ │ ├── Emitter.cc │ │ ├── emitter-power-source.mesh │ │ ├── emitter-side-cover.mesh │ │ ├── emitter.mesh │ │ ├── emitter.qrc │ │ └── spacium.png ├── bis_anim │ ├── Cargo.lock │ ├── Cargo.toml │ ├── include │ │ └── bis │ │ │ └── .PLACEHOLDER │ └── src │ │ ├── bin │ │ ├── cdef.c.txt │ │ ├── cdef_post.h.txt │ │ ├── cdef_pre.h.txt │ │ └── generate_cdef.rs │ │ ├── bis │ │ └── .PLACEHOLDER │ │ ├── ctx.rs │ │ └── lib.rs ├── config │ ├── Config.rc │ ├── config-icon.qrc │ ├── icon-v2-config.ico │ ├── icon-v2-config.png │ └── main.cc └── dsys │ ├── bin_rw.py │ ├── build.sh │ ├── cain_and_abel.py │ ├── compdec.py │ ├── dsys.ico │ ├── dsys.png │ ├── dsys_128px.png │ ├── main.py │ ├── metadata.py │ ├── requirements.txt │ ├── resc │ ├── apdisconnect.wav │ └── masterwarn.wav │ ├── tckdcmprs.py │ ├── test_compdec.py │ ├── ui.py │ ├── util.py │ ├── version.txt │ └── worker.py ├── include ├── GlobalConfig.h ├── Version.h ├── cwglx │ ├── Base │ │ ├── ElementBufferObject.h │ │ ├── Shader.h │ │ ├── ShaderProgram.h │ │ ├── Texture.h │ │ ├── VBOImpl │ │ │ └── GLM.h │ │ ├── VertexArrayObject.h │ │ ├── VertexBufferObject.h │ │ └── VertexBufferObjectImpl.h │ ├── GL │ │ ├── GL.h │ │ ├── GLImpl.h │ │ └── GLInfo.h │ ├── Object │ │ ├── Material.h │ │ ├── Object.h │ │ ├── Vertex.h │ │ └── WavefrontLoader.h │ └── Setup.h ├── ui_next │ ├── AttachmentControl.h │ ├── BodyControl.h │ ├── CloseSignallingWidget.h │ ├── CodeEdit.h │ ├── ControlPanel.h │ ├── EntityControl.h │ ├── EntityStatus.h │ ├── ExtraControl.h │ ├── FaceTrackControl.h │ ├── GLInfoDisplay.h │ ├── GLWindow.h │ ├── HelpBox.h │ ├── LicensePresenter.h │ ├── ScreenAnimationControl.h │ ├── SearchDialog.h │ ├── ShaderEdit.h │ ├── ShaderHighlighter.h │ └── SoundControl.h ├── util │ ├── CircularBuffer.h │ ├── Constants.h │ ├── Derive.h │ ├── DynLoad.h │ ├── FileUtil.h │ ├── IniLoader.h │ ├── Logger.h │ ├── Sinkrate.h │ └── Wife.h └── wgc0310 │ ├── AttachmentStatus.h │ ├── BodyAnim.h │ ├── BodyStatus.h │ ├── HeadStatus.h │ ├── Mesh.h │ ├── Screen.h │ ├── ScreenAnimationStatus.h │ ├── ScreenCurveHelper.h │ ├── ScreenGlass.h │ ├── Shader.h │ └── api │ ├── Attachment.h │ ├── ScreenAnimation.h │ └── WGAPI.h ├── main.cc ├── patch ├── README.txt ├── model │ ├── .PLACEHOLDER │ ├── DebugTexture2.png │ ├── DebugTextureHeight2.png │ ├── DebugTextureNorm2.png │ ├── TestObject.obj │ └── TestObject2.mtl └── shader │ └── .PLACEHOLDER ├── resc ├── AGPL-BRIEF ├── CC-BY-SA-BRIEF ├── PREAMBLE ├── bis │ └── interp.bis ├── eye.9.png ├── half-face-mouth-open.png ├── half-face.png ├── help │ ├── error.html │ ├── images │ │ ├── attachment-spacium.png │ │ ├── attachment.png │ │ ├── audio.png │ │ ├── body-anim-expand.png │ │ ├── body-anim-spacium.png │ │ ├── body-anim.png │ │ ├── extra.png │ │ ├── index.png │ │ ├── opengl.png │ │ ├── position.png │ │ ├── screen-anim-expand.png │ │ ├── screen-anim-typewriter.png │ │ ├── screen-audio.png │ │ ├── screen-static-expand.png │ │ ├── screen.png │ │ └── tracking │ │ │ ├── manual-audio.png │ │ │ ├── manual-mouth.png │ │ │ ├── manual.png │ │ │ ├── osf-config.png │ │ │ ├── osf.png │ │ │ ├── vts-accept.png │ │ │ ├── vts-config.png │ │ │ ├── vts-follow.png │ │ │ └── vts.png │ ├── index.css │ ├── index.html │ └── pages │ │ ├── about.html │ │ ├── advanced.html │ │ ├── attachment.html │ │ ├── audio-analysis.html │ │ ├── body-anim.html │ │ ├── extending │ │ ├── body-anim.html │ │ └── static-anim.html │ │ ├── opengl.html │ │ ├── position.html │ │ ├── screen-anim.html │ │ ├── tracking.html │ │ └── tracking │ │ ├── manual.html │ │ ├── osf.html │ │ └── vts.html ├── icon-v2.png ├── main.qrc ├── material-icons.ttf ├── model │ ├── DebugTexture.png │ ├── DebugTextureHeight.png │ ├── DebugTextureNorm.png │ ├── TestObject.mtl │ └── TestObject.obj ├── shader │ ├── common │ │ ├── emissive.frag │ │ └── emissive.vert │ ├── empty │ │ ├── empty.frag │ │ └── empty.vert │ └── standard │ │ ├── opaque.frag │ │ ├── opaque.vert │ │ ├── translucent.frag │ │ └── translucent.vert ├── splash.png └── win32 │ ├── CWGLX.rc │ ├── CWUtil.rc │ ├── Main.rc │ └── icon-v2.ico └── src ├── GlobalConfig.cc ├── cwglx ├── Base │ ├── ElementBufferObject.cc │ ├── Shader.cc │ ├── ShaderProgram.cc │ ├── Texture.cc │ └── VertexArrayObject.cc ├── GL │ └── GLInfo.cc ├── Object │ ├── Material.cc │ ├── Object.cc │ ├── Vertex.cc │ └── WavefrontLoader.cc └── Setup.cc ├── ui_next ├── AttachmentControl.cc ├── BodyControl.cc ├── CodeEdit.cc ├── ControlPanel.cc ├── EntityControl.cc ├── ExtraControl.cc ├── GLInfoDisplay.cc ├── GLWindow.cc ├── HelpBox.cc ├── LicensePresenter.cc ├── ScreenAnimationControl.cc ├── SearchDialog.cc ├── ShaderEdit.cc ├── ShaderHighlighter.cc ├── SoundControl.cc └── track │ ├── FaceTrackControl.cc │ ├── MPTrackControl.cc │ ├── ManualTrackControl.cc │ ├── OSFTrackControl.cc │ ├── TrackControlImpl.h │ └── VTSTrackControl.cc ├── util ├── Constants.cc ├── DynLoad.cc ├── FileUtil.cc └── IniLoader.cc └── wgc0310 ├── BodyAnim.cc ├── BodyStatus.cc ├── Mesh.cc ├── Screen.cc ├── ScreenAnimationStatus.cc ├── ScreenCurveHelper.cc ├── ScreenGlass.cc └── Shader.cc /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | /.qmake.cache 35 | /.qmake.stash 36 | 37 | # qtcreator generated files 38 | *.pro.user* 39 | *.user* 40 | Users*AppData* 41 | 42 | # xemacs temporary files 43 | *.flc 44 | 45 | # Vim temporary files 46 | .*.swp 47 | 48 | # Visual Studio generated files 49 | *.ib_pdb_index 50 | *.idb 51 | *.ilk 52 | *.pdb 53 | *.sln 54 | *.suo 55 | *.vcproj 56 | *vcproj.*.*.user 57 | *.ncb 58 | *.sdf 59 | *.opensdf 60 | *.vcxproj 61 | *vcxproj.* 62 | 63 | # MinGW generated files 64 | *.Debug 65 | *.Release 66 | 67 | # Python byte code 68 | *.pyc 69 | 70 | # Binaries 71 | # -------- 72 | *.dll 73 | *.exe 74 | 75 | # 傻逼 IDEA 能不能不要问我要不要添加你那个破 .idea,要不要添加你心里没点 B 树吗,操你妈 76 | .idea 77 | 78 | # 傻逼 IDEA 不会 shadow build? 79 | cmake-build* 80 | 81 | LICENSE.AGREED 82 | 83 | # 排除模型文件,此 obj 非彼 obj 84 | !resc/model/*.obj 85 | !patch/model/*.obj 86 | 87 | # Rust 组件的构建产物 88 | **/target 89 | 90 | # 由 generate_cdefs 动态生成 91 | extra/bis_anim/include/bis/BISContext.h 92 | extra/bis_anim/src/bis/BISContext.cc 93 | 94 | extra/dsys/*.spec 95 | **/build 96 | **/dist 97 | *.tck 98 | *.tck.dec 99 | *.onnx 100 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Project-WG 2 | 3 | Author: Chuigda 4 | 5 | 试图用 OpenGL 3.3 画个可爱(?大概吧)的小机器人。 6 | 7 | Try drawing a cute (?maybe) robot with OpenGL 3.3 8 | 9 | image::./blobs/come-to-dd-me.jpg[快来 D 我] 10 | 11 | 在 link:https://live.bilibili.com/10309712[Bilibili] 观看我的直播 12 | 13 | Watch my live at link:https://live.bilibili.com/10309712[Bilibili] 14 | 15 | == ⚠️⚠️⚠️ 警告:已弃坑 ⚠️⚠️⚠️ 16 | [quote] 17 | ____ 18 | 去隔壁 link:https://github.com/chuigda/Project-WGX[Project-WGX]. 19 | 20 | Goto link:https://github.com/chuigda/Project-WGX[Project-WGX] instead. 21 | ____ 22 | 23 | == ⚠️⚠️⚠️ 警告:有彩笔 ⚠️⚠️⚠️ 24 | [quote] 25 | ____ 26 | 虽然从 0.4.0 之后项目改用 OpenGL 可编程管线了,但还是写的很菜。我也不怎么懂图形学的概念,只是东拼西凑一下碰巧能把东西画出来。代码质量基本就是摆烂,各种命名都有很多临时起意加玩梗的要素。 27 | 所以这项目的代码你看了真的就只能图一乐,如果你抱着学习 OpenGL 或者图形学的想法走进这个仓库,那最好还是去找个别的项目学习。 28 | 29 | 当然,如果你真的喜欢这个项目,并且在“使用”过程中遇到了困难,欢迎来 issue 页面撕逼。 30 | 31 | Though this project migrates to OpenGL programmable pipeline since 0.4.0, my CG programming is still too vegetable. I don't know much about CG so these code "just happen to work". The code quality 32 | is also very poor, with namings of tons of jokes and memes. So you may only get "Kennedy-ed" if you read these code. If you'd like to learn OpenGL or CG, better to find some other project. 33 | 34 | Or, maybe you really like this project and had some problem while "using" it, then come to the "issue" page 35 | ____ 36 | 37 | == 许可证 38 | * Project-WG 的代码使用 link:https://www.gnu.org/licenses/agpl-3.0.txt[AGPLv3] 授权 39 | * 角色“WGC0310”以 link:https://creativecommons.org/licenses/by-sa/4.0/legalcode.zh-Hans[CC BY-SA 4.0] 授权 40 | 41 | * Code of Project-WG is licensed with link:https://www.gnu.org/licenses/agpl-3.0.txt[AGPLv3] 42 | * Character "WGC0310" is licensed with link:https://creativecommons.org/licenses/by-sa/4.0/legalcode.zh-Hans[CC BY-SA 4.0] 43 | 44 | == 其他信息 45 | * 机器人图标取自 link:https://www.flaticon.com/free-icons/robot[Freepik - Flaticon] 46 | * Robot icon was taken from by link:https://www.flaticon.com/free-icons/robot[Freepik - Flaticon] 47 | -------------------------------------------------------------------------------- /animations/body/0-static.anim: -------------------------------------------------------------------------------- 1 | n=静止状态 2 | 3 | s 4 | l 1 15.0 25 5 | r 1 15.0 25 6 | 7 | l 3 15.0 25 8 | r 3 -15.0 25 -------------------------------------------------------------------------------- /animations/body/0-static.bis: -------------------------------------------------------------------------------- 1 | #attribute name 静止状态 2 | #import interp.bis 3 | 4 | void main() { 5 | g_arm_l1 = 0.0; 6 | g_arm_r1 = 0.0; 7 | 8 | g_arm_l3 = 0.0; 9 | g_arm_r3 = 0.0; 10 | 11 | int i; 12 | for (i = 1; i <= 25; i++) { 13 | float dx = 15.0 * interp(1.0, 25.0, float(i)); 14 | g_arm_l1 = dx; 15 | g_arm_r1 = dx; 16 | g_arm_l3 = dx; 17 | g_arm_r3 = -dx; 18 | yield; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /animations/body/1-punch.anim: -------------------------------------------------------------------------------- 1 | n=给你一拳 2 | 3 | # 抬手 4 | s 5 | l 0 -90.0 45 6 | l 1 90.0 45 7 | l 3 105.0 45 8 | 9 | # 左手出拳 10 | s 11 | l 1 -60.0 20 12 | l 3 -60.0 20 13 | 14 | s 15 | l 1 -45.0 10 16 | l 3 -45.0 10 17 | 18 | # 左手收拳 19 | s 20 | l 1 60.0 20 21 | l 3 60.0 20 22 | 23 | s 24 | l 1 45.0 10 25 | l 3 45.0 10 26 | 27 | # 放手 28 | s 29 | l 0 90.0 45 30 | l 1 -90.0 45 31 | l 3 -105.0 45 32 | -------------------------------------------------------------------------------- /animations/body/2-two-punches.anim: -------------------------------------------------------------------------------- 1 | n=梆梆两拳 2 | 3 | # 抬手 4 | s 5 | l 0 -90.0 45 6 | l 1 90.0 45 7 | l 3 105.0 45 8 | r 0 -90.0 45 9 | r 1 90.0 45 10 | r 3 -105.0 45 11 | 12 | # 左手出拳 13 | s 14 | l 1 -60.0 20 15 | l 3 -60.0 20 16 | 17 | s 18 | l 1 -45.0 10 19 | l 3 -45.0 10 20 | 21 | # 右手出拳,左手收拳 22 | s 23 | r 1 -60.0 20 24 | r 3 60.0 20 25 | l 1 60.0 20 26 | l 3 60.0 20 27 | 28 | s 29 | r 1 -45.0 10 30 | r 3 45.0 10 31 | l 1 45.0 10 32 | l 3 45.0 10 33 | 34 | # 右手收拳 35 | s 36 | r 1 60.0 20 37 | r 3 -60.0 20 38 | 39 | s 40 | r 1 45.0 10 41 | r 3 -45.0 10 42 | 43 | # 放手 44 | s 45 | l 0 90.0 45 46 | l 1 -90.0 45 47 | l 3 -105.0 45 48 | r 0 90.0 45 49 | r 1 -90.0 45 50 | r 3 105.0 45 -------------------------------------------------------------------------------- /animations/body/3-spacium.anim: -------------------------------------------------------------------------------- 1 | # 别问我为什么是集束射线的动作,这个机器人不穿模做不出斯派修姆 2 | n=斯派修姆 3 | 4 | # 第一段动作 5 | s 6 | # L/R 第几个关节 转动角度 在多少帧内完成 7 | l 0 -90.0 45 8 | l 2 -90.0 45 9 | r 0 -90.0 45 10 | 11 | # 第二段动作 12 | s 13 | # L/R 第几个关节 转动角度 在多少帧内完成 14 | l 3 90.0 45 15 | r 3 -90.0 45 16 | -------------------------------------------------------------------------------- /animations/body/3-spacium.bis: -------------------------------------------------------------------------------- 1 | #attribute name 斯派修姆 2 | #import interp.bis 3 | 4 | void main() { 5 | g_arm_l0 = 0.0; 6 | g_arm_l2 = 0.0; 7 | g_arm_r0 = 0.0; 8 | g_arm_l3 = 0.0; 9 | g_arm_r3 = 0.0; 10 | yield; 11 | 12 | int i; 13 | for (i = 1; i <= 45; i++) { 14 | float value = -90.0 * interp(1.0, 45.0, float(i)); 15 | g_arm_l0 = value; 16 | g_arm_l2 = value; 17 | g_arm_r0 = value; 18 | yield; 19 | } 20 | 21 | for (i = 1; i <= 45; i++) { 22 | float value = 90.0 * interp(1.0, 45.0, float(i)); 23 | g_arm_l3 = value; 24 | g_arm_r3 = -value; 25 | yield; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /animations/body/4-zeperion.anim: -------------------------------------------------------------------------------- 1 | # 哉佩利奥 2 | n=哉佩利奥 3 | 4 | # 起手动作 5 | s 6 | l 2 -90.0 15 7 | r 2 90.0 15 8 | 9 | s 10 | l 3 90.0 30 11 | r 3 -90.0 30 12 | 13 | # 冲拳 14 | s 15 | l 0 -90.0 45 16 | r 0 -90.0 45 17 | 18 | l 1 -15.0 45 19 | r 1 -15.0 45 20 | 21 | l 2 90.0 45 22 | r 2 -90.0 45 23 | 24 | l 3 -90.0 30 25 | r 3 90.0 30 26 | 27 | # 间隔 28 | s 29 | l 0 0.0 15 30 | 31 | # 伸开手臂 32 | s 33 | l 1 105.0 90 34 | r 1 105.0 90 35 | 36 | # 光线! 37 | s 38 | l 1 -90.0 45 39 | r 1 -90.0 45 40 | l 2 -90.0 45 41 | l 3 90.0 45 42 | r 3 -90.0 45 -------------------------------------------------------------------------------- /animations/dynamic/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/dynamic/.PLACEHOLDER -------------------------------------------------------------------------------- /animations/static/0-加载图像.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/0-加载图像.png -------------------------------------------------------------------------------- /animations/static/1-wink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/1-wink.png -------------------------------------------------------------------------------- /animations/static/2-不开心.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/2-不开心.png -------------------------------------------------------------------------------- /animations/static/3-寄了.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/3-寄了.png -------------------------------------------------------------------------------- /animations/static/4-先辈恶臭.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/4-先辈恶臭.png -------------------------------------------------------------------------------- /animations/static/5-流汗黄豆.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/5-流汗黄豆.png -------------------------------------------------------------------------------- /animations/static/6-蓝屏.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/animations/static/6-蓝屏.png -------------------------------------------------------------------------------- /attachments/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/attachments/.PLACEHOLDER -------------------------------------------------------------------------------- /blobs/come-to-dd-me.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/come-to-dd-me.jpg -------------------------------------------------------------------------------- /blobs/designs/README.adoc: -------------------------------------------------------------------------------- 1 | = WGC-0310 的设计案及其许可证 2 | 3 | == B 方案 4 | 5 | 由洛阳酉告文化传播有限公司提供,经友好协商后以 link:https://creativecommons.org/licenses/by-sa/4.0/legalcode.zh-Hans[CC-BY-SA 4.0] 协议发布,**原作者保留署名权**。 6 | 7 | 原作者联系方式: 17530855327。 8 | 9 | image::设计方案B.png[] 10 | 11 | == C 方案 12 | 13 | 使用人工智能生成。 14 | 15 | image::设计案C1.jpg[] 16 | 17 | image::设计案C2.jpg[] 18 | 19 | == 最终案 (draft, verylow) 20 | 21 | [quote] 22 | ____ 23 | 尚未确定 24 | ____ 25 | -------------------------------------------------------------------------------- /blobs/designs/设计方案B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/designs/设计方案B.png -------------------------------------------------------------------------------- /blobs/designs/设计方案B.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/designs/设计方案B.psd -------------------------------------------------------------------------------- /blobs/designs/设计案C1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/designs/设计案C1.jpg -------------------------------------------------------------------------------- /blobs/designs/设计案C2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/designs/设计案C2.jpg -------------------------------------------------------------------------------- /blobs/render-output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/blobs/render-output.jpg -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [common] 2 | # 所有窗口常居顶端 3 | stay_on_top=false 4 | # 启用背景填充 5 | fill_background=false 6 | # 自定义背景颜色 7 | background_r=0 8 | background_g=0 9 | background_b=0 10 | 11 | [render] 12 | # 多重采样抗锯齿 13 | multisampling=true 14 | # 多重采样抗锯齿样本数 15 | multisampling_samples=8 16 | # 线条平滑 17 | line_smooth=true 18 | # 各向异性过滤 19 | anisotropy_filter=true 20 | # 纹理采样方式,true=线性采样,false=临近采样 21 | linear_sampling=true 22 | 23 | [control] 24 | # 默认模式 25 | default_mode=none 26 | 27 | [control.vts] 28 | # WebSocket 端口 29 | websocket_port=8001 30 | 31 | [control.osf] 32 | # UDP 端口 33 | udp_port=11573 34 | # XYZ 校正 35 | correction_x=0 36 | correction_y=0 37 | correction_z=0 38 | # 平滑 39 | smooth=8 40 | -------------------------------------------------------------------------------- /extra/animations/Taunter/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/animations/Taunter/1.png -------------------------------------------------------------------------------- /extra/animations/Taunter/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/animations/Taunter/2.png -------------------------------------------------------------------------------- /extra/animations/Taunter/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/animations/Taunter/3.png -------------------------------------------------------------------------------- /extra/animations/Taunter/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/animations/Taunter/4.png -------------------------------------------------------------------------------- /extra/animations/Taunter/Taunter.cc: -------------------------------------------------------------------------------- 1 | #include "wgc0310/api/ScreenAnimation.h" 2 | 3 | #include 4 | #include "cwglx/GLImpl.h" 5 | #include "cwglx/Texture.h" 6 | #include "util/Constants.h" 7 | 8 | static const std::uint8_t TauntFrameSequence[] = { 9 | 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 2, 1, 1, 10 | 0, 0, 0, 1, 3, 1, 11 | 0, 0, 1, 3, 1, 12 | 0, 0, 1, 2, 3, 3, 2, 1, 13 | 0, 0, 1, 3, 2, 1, 14 | 0, 1, 1, 3, 3, 2, 1, 15 | 0, 0, 0, 1, 3, 3, 1, 16 | 0, 0, 2, 2, 1, 17 | 0, 2, 3, 1, 18 | 0, 1, 2, 3, 3, 1, 19 | 0, 0, 2, 3, 2, 20 | 0, 0, 1, 1, 3, 3, 3, 1, 1, 21 | 0, 0, 0, 0, 1, 1, 3, 3, 2, 1, 22 | 0, 0, 0, 1, 2, 3, 2, 1, 23 | 0, 0, 0, 0, 1, 2, 3, 2, 1, 24 | 0, 0, 0, 2, 3, 1, 25 | 0, 1, 1, 3, 3, 3, 1, 1, 26 | 0, 0, 0, 1, 3, 3, 1, 27 | 0, 0, 1, 3, 1, 28 | 0, 0, 1, 3, 1, 29 | 0, 0, 1, 3, 3, 30 | 0, 0, 1, 1, 3, 3, 2, 1, 31 | 0, 0, 1, 0 32 | }; 33 | 34 | class Taunter final : public wgc0310::WGAPIAnimation { 35 | public: 36 | Taunter() = default; 37 | 38 | ~Taunter() final = default; 39 | 40 | const char *GetName() noexcept final { 41 | return "电摇嘲讽"; 42 | } 43 | 44 | QWidget *GetControlWidget() noexcept final { return nullptr; } 45 | 46 | void NextTick() noexcept final { 47 | m_CurrentTick += 1; 48 | if (m_CurrentTick / 3 >= cw::countof(TauntFrameSequence)) { 49 | m_CurrentTick = 0; 50 | } 51 | } 52 | 53 | void Rewind() noexcept final { 54 | m_CurrentTick = 0; 55 | } 56 | 57 | bool Initialize(GLFunctions* f) noexcept final { 58 | m_TexturePack[0] = std::make_unique(QImage(":/1.png"), f); 59 | m_TexturePack[1] = std::make_unique(QImage(":/2.png"), f); 60 | m_TexturePack[2] = std::make_unique(QImage(":/3.png"), f); 61 | m_TexturePack[3] = std::make_unique(QImage(":/4.png"), f); 62 | return true; 63 | } 64 | 65 | void Draw(GLFunctions* f) noexcept final { 66 | std::uint8_t frameId = TauntFrameSequence[m_CurrentTick / 3]; 67 | cw::Texture2D *texture = m_TexturePack[frameId].get(); 68 | 69 | texture->BeginTexture(f); 70 | 71 | f->glColor3f(1.0f, 1.0f, 1.0f); 72 | f->glBegin(GL_QUADS); 73 | { 74 | f->glTexCoord2f(0.0f, 1.0f); 75 | f->glVertex2f(-320.0f, 240.0f); 76 | 77 | f->glTexCoord2f(0.0f, 0.0f); 78 | f->glVertex2f(-320.0f, -240.0f); 79 | 80 | f->glTexCoord2f(1.0f, 0.0f); 81 | f->glVertex2f(320.0f, -240.0f); 82 | 83 | f->glTexCoord2f(1.0f, 1.0f); 84 | f->glVertex2f(320.0f, 240.0f); 85 | } 86 | f->glEnd(); 87 | } 88 | 89 | void Delete(GLFunctions *f) noexcept final { 90 | for (auto &texture : m_TexturePack) { 91 | texture->DeleteTexture(f); 92 | } 93 | } 94 | 95 | private: 96 | std::array, 4> m_TexturePack; 97 | std::size_t m_CurrentTick = 0; 98 | }; 99 | 100 | extern "C" { 101 | std::uint32_t WGAPI GetWGAPIVersion() { 102 | return WGAPI_VERSION; 103 | } 104 | 105 | wgc0310::WGAPIAnimation * WGAPI LoadAnimation() { 106 | return new Taunter(); 107 | } 108 | } // extern "C" 109 | -------------------------------------------------------------------------------- /extra/animations/Taunter/taunter.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.png 4 | 2.png 5 | 3.png 6 | 4.png 7 | 8 | 9 | -------------------------------------------------------------------------------- /extra/animations/TypeWriter/TypeWriter.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/Texture.h" 2 | #include "cwglx/GLImpl.h" 3 | #include "wgc0310/api/ScreenAnimation.h" 4 | #include "TypeWriterControl.h" 5 | 6 | class TypeWriter final : public wgc0310::WGAPIAnimation { 7 | public: 8 | TypeWriter() 9 | : m_NeedsUpdate(false), 10 | m_ControlWidget(new TypeWriterControl(&m_NeedsUpdate)), 11 | m_Texture(nullptr) 12 | {} 13 | 14 | ~TypeWriter() final = default; 15 | 16 | const char *GetName() noexcept final { 17 | return "打字机"; 18 | } 19 | 20 | QWidget *GetControlWidget() noexcept final { return m_ControlWidget.get(); } 21 | 22 | void NextTick() noexcept final {} 23 | 24 | void Rewind() noexcept final {} 25 | 26 | bool Initialize(GLFunctions* f) noexcept final { 27 | m_Texture = std::make_unique(m_ControlWidget->capture(), f); 28 | return true; 29 | } 30 | 31 | void Draw(GLFunctions* f) noexcept final { 32 | if (m_NeedsUpdate) { 33 | m_Texture->UpdateContent(f, m_ControlWidget->capture()); 34 | m_NeedsUpdate = false; 35 | } 36 | 37 | m_Texture->BeginTexture(f); 38 | 39 | f->glColor3f(1.0f, 1.0f, 1.0f); 40 | f->glBegin(GL_QUADS); 41 | { 42 | f->glTexCoord2f(0.0f, 1.0f); 43 | f->glVertex2f(-320.0f, 240.0f); 44 | 45 | f->glTexCoord2f(0.0f, 0.0f); 46 | f->glVertex2f(-320.0f, -240.0f); 47 | 48 | f->glTexCoord2f(1.0f, 0.0f); 49 | f->glVertex2f(320.0f, -240.0f); 50 | 51 | f->glTexCoord2f(1.0f, 1.0f); 52 | f->glVertex2f(320.0f, 240.0f); 53 | } 54 | f->glEnd(); 55 | } 56 | 57 | void Delete(GLFunctions *f) noexcept final { 58 | m_Texture->DeleteTexture(f); 59 | } 60 | 61 | private: 62 | bool m_NeedsUpdate; 63 | std::unique_ptr m_ControlWidget; 64 | std::unique_ptr m_Texture; 65 | }; 66 | 67 | extern "C" { 68 | std::uint32_t WGAPI GetWGAPIVersion() { 69 | return WGAPI_VERSION; 70 | } 71 | 72 | wgc0310::WGAPIAnimation *WGAPI LoadAnimation() { 73 | return new TypeWriter(); 74 | } 75 | } // extern "C" 76 | -------------------------------------------------------------------------------- /extra/animations/TypeWriter/TypeWriterControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_EXTRA_TYPEWRITER_CONTROL_H 2 | #define PROJECT_WG_EXTRA_TYPEWRITER_CONTROL_H 3 | 4 | #include 5 | #include 6 | 7 | class QPlainTextEdit; 8 | 9 | class TypeWriterControl : public QWidget { 10 | public: 11 | explicit TypeWriterControl(bool *contentChanged = nullptr); 12 | [[nodiscard]] QImage capture() const; 13 | 14 | private slots: 15 | void updateFont(); 16 | void updateText(); 17 | void updateCanvas(); 18 | 19 | private: 20 | bool *m_ContentChanged; 21 | QWidget *m_PreviewWidget; 22 | QPlainTextEdit *m_TextEdit; 23 | 24 | QString m_DisplayText; 25 | QColor m_ForeColor; 26 | QColor m_BackColor; 27 | QFont m_Font; 28 | QFontMetrics m_FontMetrics; 29 | int m_AlignmentFlag; 30 | }; 31 | 32 | #endif // PROJECT_WG_EXTRA_TYPEWRITER_CONTROL_H 33 | -------------------------------------------------------------------------------- /extra/attachments/Emitter/emitter-side-cover.mesh: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 2 | # www.blender.org 3 | o Emitter-side-cover 4 | v 3.903062 4.026625 1.800001 5 | v 3.903062 4.026626 -1.799999 6 | v 17.090714 3.449306 1.800002 7 | v 17.090714 3.449306 -1.799998 8 | v 17.090714 3.872606 1.800001 9 | v 17.090714 3.872607 -1.799999 10 | v 3.903062 4.501625 1.800001 11 | v 3.903062 4.501626 -1.800000 12 | v 17.090714 4.372606 1.800001 13 | v 17.090714 4.372607 -1.799999 14 | v 3.903062 4.026625 2.050001 15 | v 17.090714 3.449306 2.050001 16 | v 17.090714 3.872606 2.050001 17 | v 3.903062 4.026626 -2.049999 18 | v 17.090714 3.449306 -2.049999 19 | v 17.090714 3.872607 -2.049999 20 | v 3.903062 4.401620 2.050000 21 | v 3.903062 4.501625 1.950000 22 | v 17.090714 4.372606 1.950001 23 | v 17.090714 4.272601 2.050001 24 | v 3.903062 4.501626 -1.949999 25 | v 3.903062 4.401621 -2.049999 26 | v 17.090714 4.272602 -2.049999 27 | v 17.090714 4.372607 -1.949998 28 | s 0 29 | f 10 21 8 30 | f 1 17 18 31 | f 3 11 1 32 | f 2 15 4 33 | f 8 22 14 34 | f 13 17 11 35 | f 5 19 13 36 | f 14 23 16 37 | f 15 23 10 38 | f 17 19 18 39 | f 24 22 21 40 | f 7 19 9 41 | f 10 24 21 42 | f 18 7 1 43 | f 1 11 17 44 | f 3 12 11 45 | f 2 14 15 46 | f 14 2 8 47 | f 8 21 22 48 | f 11 12 13 49 | f 13 20 17 50 | f 12 3 5 51 | f 5 9 19 52 | f 19 20 13 53 | f 13 12 5 54 | f 16 15 14 55 | f 14 22 23 56 | f 6 4 15 57 | f 15 16 23 58 | f 23 24 10 59 | f 10 6 15 60 | f 17 20 19 61 | f 24 23 22 62 | f 7 18 19 63 | -------------------------------------------------------------------------------- /extra/attachments/Emitter/emitter.mesh: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 2 | # www.blender.org 3 | o Emitter 4 | v 3.653062 3.376625 1.350001 5 | v 3.653062 3.376625 -1.349999 6 | v 17.340714 2.799306 1.350001 7 | v 17.340714 2.799306 -1.349998 8 | v 3.653062 3.876625 1.800001 9 | v 3.653062 3.876625 -1.800000 10 | v 17.340714 3.299306 1.800002 11 | v 17.340714 3.299306 -1.799998 12 | v 3.653062 3.876625 1.800001 13 | v 3.653062 3.876625 -1.800000 14 | v 17.340714 3.299306 1.800002 15 | v 17.340714 3.299306 -1.799998 16 | v 17.340714 3.872606 1.800001 17 | v 17.340714 3.872607 -1.799999 18 | v 3.653062 4.376625 1.800001 19 | v 3.653062 4.376626 -1.800000 20 | v 17.340714 4.372606 1.800001 21 | v 17.340714 4.372607 -1.799999 22 | v 3.653135 4.626626 -1.800000 23 | v 3.653135 4.626625 1.800001 24 | v 17.340786 4.622607 -1.799999 25 | v 17.340786 4.622606 1.800001 26 | v 3.653135 4.626625 0.800001 27 | v 17.340786 4.622606 0.800001 28 | v 3.653135 4.626625 -0.800000 29 | v 17.340786 4.622606 -0.799998 30 | v 3.653135 4.376625 0.425001 31 | v 17.340786 4.372606 0.425001 32 | v 3.653135 4.376625 -0.425000 33 | v 17.340786 4.372606 -0.424998 34 | v 3.653211 4.883852 -1.549999 35 | v 17.340862 4.879833 -1.549998 36 | v 3.653211 4.883851 1.550001 37 | v 17.340862 4.879832 1.550002 38 | v 3.653211 4.883851 0.800001 39 | v 17.340862 4.879832 0.800001 40 | v 3.653211 4.883851 -0.800000 41 | v 17.340862 4.879832 -0.799998 42 | s 0 43 | f 4 1 2 44 | f 2 8 4 45 | f 7 1 3 46 | f 4 7 3 47 | f 5 2 1 48 | f 7 9 5 49 | f 5 10 6 50 | f 6 12 8 51 | f 8 11 7 52 | f 14 11 12 53 | f 15 10 9 54 | f 18 13 14 55 | f 22 15 17 56 | f 16 21 18 57 | f 24 34 22 58 | f 24 27 23 59 | f 29 26 25 60 | f 22 17 24 61 | f 24 17 28 62 | f 18 21 26 63 | f 26 30 18 64 | f 20 23 15 65 | f 23 27 15 66 | f 19 16 25 67 | f 25 16 29 68 | f 30 27 28 69 | f 36 33 34 70 | f 31 38 32 71 | f 25 31 19 72 | f 33 23 20 73 | f 19 32 21 74 | f 32 26 21 75 | f 34 20 22 76 | f 26 37 25 77 | f 23 36 24 78 | f 10 18 12 79 | f 17 9 11 80 | f 4 3 1 81 | f 2 6 8 82 | f 7 5 1 83 | f 4 8 7 84 | f 5 6 2 85 | f 7 11 9 86 | f 5 9 10 87 | f 6 10 12 88 | f 8 12 11 89 | f 14 13 11 90 | f 15 16 10 91 | f 18 17 13 92 | f 22 20 15 93 | f 16 19 21 94 | f 24 36 34 95 | f 24 28 27 96 | f 29 30 26 97 | f 30 29 27 98 | f 36 35 33 99 | f 31 37 38 100 | f 25 37 31 101 | f 33 35 23 102 | f 19 31 32 103 | f 32 38 26 104 | f 34 33 20 105 | f 26 38 37 106 | f 23 35 36 107 | f 10 16 18 108 | f 17 15 9 109 | -------------------------------------------------------------------------------- /extra/attachments/Emitter/emitter.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | emitter.mesh 4 | emitter-power-source.mesh 5 | emitter-side-cover.mesh 6 | spacium.png 7 | 8 | 9 | -------------------------------------------------------------------------------- /extra/attachments/Emitter/spacium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/attachments/Emitter/spacium.png -------------------------------------------------------------------------------- /extra/bis_anim/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "bis_anim" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "pr21", 10 | ] 11 | 12 | [[package]] 13 | name = "pr21" 14 | version = "0.1.0" 15 | source = "git+https://github.com/Pr47/Project-21?rev=dffefa87e3231ae2341c7d58e8eff6ad1db67c86#dffefa87e3231ae2341c7d58e8eff6ad1db67c86" 16 | dependencies = [ 17 | "smallvec", 18 | "xjbutil", 19 | ] 20 | 21 | [[package]] 22 | name = "smallvec" 23 | version = "1.10.0" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 26 | 27 | [[package]] 28 | name = "unchecked_unwrap" 29 | version = "4.0.0" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "3225965522cd8ec8a857c1496adf6c17ecb9c0de554a09dbdaa89080bbb74088" 32 | 33 | [[package]] 34 | name = "xjbutil" 35 | version = "0.9.0-DELTA" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "60d217d9f88a7bc238cf5e31a2ee1fcef7865dcbeded2b85d1c672a5ad72757f" 38 | dependencies = [ 39 | "unchecked_unwrap", 40 | ] 41 | -------------------------------------------------------------------------------- /extra/bis_anim/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bis_anim" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | [lib] 8 | crate-type = ["lib", "cdylib"] 9 | 10 | [[bin]] 11 | name = "generate_cdefs" 12 | path = "src/bin/generate_cdef.rs" 13 | 14 | [dependencies] 15 | pr21 = { git = "https://github.com/Pr47/Project-21", rev = "dffefa87e3231ae2341c7d58e8eff6ad1db67c86" } 16 | -------------------------------------------------------------------------------- /extra/bis_anim/include/bis/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/bis_anim/include/bis/.PLACEHOLDER -------------------------------------------------------------------------------- /extra/bis_anim/src/bin/cdef.c.txt: -------------------------------------------------------------------------------- 1 | #include "bis/BISContext.h" 2 | 3 | static_assert(sizeof(bis::Context) == {}, "Unexpected size mismatch"); 4 | -------------------------------------------------------------------------------- /extra/bis_anim/src/bin/cdef_post.h.txt: -------------------------------------------------------------------------------- 1 | }; 2 | 3 | } // namespace bis 4 | 5 | #endif // PROJECT_WG_BIS_CONTEXT_H 6 | -------------------------------------------------------------------------------- /extra/bis_anim/src/bin/cdef_pre.h.txt: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_BIS_CONTEXT_H 2 | #define PROJECT_WG_BIS_CONTEXT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace bis { 8 | 9 | extern "C" struct Context { 10 | -------------------------------------------------------------------------------- /extra/bis_anim/src/bin/generate_cdef.rs: -------------------------------------------------------------------------------- 1 | use std::fs::OpenOptions; 2 | use std::io::Write; 3 | use pr21::io_ctx::{IOContext, Type21}; 4 | use bis_anim::ctx::Context; 5 | 6 | fn type21_to_ctype(input: Type21) -> &'static str { 7 | match input { 8 | Type21::Int32 => "std::int32_t", 9 | Type21::Float32 => "float", 10 | } 11 | } 12 | 13 | fn main() { 14 | let mut header_file = OpenOptions::new() 15 | .read(false) 16 | .write(true) 17 | .create(true) 18 | .truncate(true) 19 | .open("include/bis/BISContext.h") 20 | .unwrap(); 21 | 22 | write!(header_file, "{}", include_str!("cdef_pre.h.txt")).unwrap(); 23 | for (_, field, ty) in ::metadata() { 24 | writeln!( 25 | header_file, 26 | " {} {};", 27 | type21_to_ctype(ty), 28 | field 29 | ).unwrap(); 30 | } 31 | write!(header_file, "{}", include_str!("cdef_post.h.txt")).unwrap(); 32 | 33 | let mut source_file = OpenOptions::new() 34 | .read(false) 35 | .write(true) 36 | .create(true) 37 | .truncate(true) 38 | .open("src/bis/BISContext.cc") 39 | .unwrap(); 40 | write!(source_file, include_str!("cdef.c.txt"), std::mem::size_of::()).unwrap(); 41 | } 42 | -------------------------------------------------------------------------------- /extra/bis_anim/src/bis/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/bis_anim/src/bis/.PLACEHOLDER -------------------------------------------------------------------------------- /extra/bis_anim/src/ctx.rs: -------------------------------------------------------------------------------- 1 | use pr21::define_io_ctx; 2 | 3 | define_io_ctx!(struct Context { 4 | // input variables 5 | g_in_x => in_x: f32, 6 | g_in_y => in_y: f32, 7 | g_in_z => in_z: f32, 8 | 9 | // frame counter 10 | g_frame => frame: i32, 11 | 12 | // body status 13 | g_waist_x => waist_x: f32, 14 | g_waist_y => waist_y: f32, 15 | g_waist_z => waist_z: f32, 16 | 17 | g_head_x => head_x: f32, 18 | g_head_y => head_y: f32, 19 | g_head_z => head_z: f32, 20 | 21 | // arms, legs and hand status 22 | g_arm_l0 => arm_l0: f32, 23 | g_arm_l1 => arm_l1: f32, 24 | g_arm_l2 => arm_l2: f32, 25 | g_arm_l3 => arm_l3: f32, 26 | g_arm_l4 => arm_l4: f32, 27 | 28 | g_arm_r0 => arm_r0: f32, 29 | g_arm_r1 => arm_r1: f32, 30 | g_arm_r2 => arm_r2: f32, 31 | g_arm_r3 => arm_r3: f32, 32 | g_arm_r4 => arm_r4: f32, 33 | 34 | g_leg_l0 => leg_l0: f32, 35 | g_leg_l1 => leg_l1: f32, 36 | g_leg_l2 => leg_l2: f32, 37 | g_leg_l3 => leg_l3: f32, 38 | 39 | g_leg_r0 => leg_r0: f32, 40 | g_leg_r1 => leg_r1: f32, 41 | g_leg_r2 => leg_r2: f32, 42 | g_leg_r3 => leg_r3: f32, 43 | 44 | // helper variables 45 | g_i0 => i0: i32, 46 | g_i1 => i1: i32, 47 | g_i2 => i2: i32, 48 | g_i3 => i3: i32, 49 | g_i4 => i4: i32, 50 | g_i5 => i5: i32, 51 | 52 | g_f0 => f0: f32, 53 | g_f1 => f1: f32, 54 | g_f2 => f2: f32, 55 | g_f3 => f3: f32, 56 | g_f4 => f4: f32, 57 | g_f5 => f5: f32, 58 | 59 | // config parameters 60 | g_cfg_i0 => cfg_i0: i32, 61 | g_cfg_i1 => cfg_i1: i32, 62 | g_cfg_i2 => cfg_i2: i32, 63 | g_cfg_i3 => cfg_i3: i32, 64 | 65 | g_cfg_f0 => cfg_f0: f32, 66 | g_cfg_f1 => cfg_f1: f32, 67 | g_cfg_f2 => cfg_f2: f32, 68 | g_cfg_f3 => cfg_f3: f32 69 | }); 70 | 71 | #[cfg(test)] 72 | #[test] 73 | fn test_ctx_size() { 74 | use pr21::io_ctx::IOContext; 75 | 76 | dbg!(std::mem::size_of::()); 77 | eprintln!("metadata = {:?}", ::metadata()); 78 | } 79 | -------------------------------------------------------------------------------- /extra/bis_anim/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod ctx; -------------------------------------------------------------------------------- /extra/config/Config.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CW_WIN32_RESOURCE 4 | #include "Version.h" 5 | 6 | 0 ICON DISCARDABLE "icon-v2-config.ico" 7 | 8 | 1 VERSIONINFO 9 | FILEVERSION 0,1,0,0 10 | PRODUCTVERSION WG_PRODUCT_VERSION 11 | FILEOS VOS_NT 12 | FILETYPE VFT_APP 13 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 14 | #if defined(WG_PRIVATE_BUILD_INFO) 15 | FILEFLAGS VS_FF_PRIVATEBUILD 16 | #endif 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "040904E4" 21 | BEGIN 22 | VALUE "ProductName", WG_PRODUCT_NAME 23 | VALUE "ProductVersion", WG_PRODUCT_VERSION_STRING 24 | VALUE "CompanyName", COMPANY_NAME 25 | VALUE "LegalCopyright", COPYRIGHT_INFO 26 | VALUE "FileDescription", "Project-WG Configurator" 27 | VALUE "FileVersion", WG_PRODUCT_VERSION_STRING 28 | VALUE "OriginalFilename", "Config.exe" 29 | #if defined(WG_PRIVATE_BUILD_INFO) 30 | VALUE "PrivateBuild", WG_PRIVATE_BUILD_INFO 31 | #endif 32 | END 33 | END 34 | BLOCK "VarFileInfo" 35 | BEGIN 36 | VALUE "Translation", 0x0409, 0x04B0 37 | END 38 | END 39 | -------------------------------------------------------------------------------- /extra/config/config-icon.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-v2-config.png 5 | 6 | -------------------------------------------------------------------------------- /extra/config/icon-v2-config.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/config/icon-v2-config.ico -------------------------------------------------------------------------------- /extra/config/icon-v2-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/config/icon-v2-config.png -------------------------------------------------------------------------------- /extra/dsys/bin_rw.py: -------------------------------------------------------------------------------- 1 | def write_binseq(file, content: bytes): 2 | file.write(len(content).to_bytes(4, byteorder="little")) 3 | file.write(content) 4 | 5 | 6 | def read_binseq(file): 7 | length = file.read(4) 8 | if length == b"": 9 | return None 10 | length = int.from_bytes(length, byteorder="little") 11 | content = file.read(length) 12 | if len(content) != length: 13 | raise Exception("Unexpected EOF") 14 | return content 15 | -------------------------------------------------------------------------------- /extra/dsys/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | pyinstaller \ 4 | -w \ 5 | -n dsys \ 6 | --version-file version.txt \ 7 | -i dsys.ico \ 8 | main.py \ 9 | --add-data "resc;resc" \ 10 | -y \ 11 | --clean 12 | -------------------------------------------------------------------------------- /extra/dsys/cain_and_abel.py: -------------------------------------------------------------------------------- 1 | Cain_And_Abel = """ --- CAIN AND ABEL --- 2 | 3 | (Genesis 4:1-16) 4 | 5 | 1 And Adam knew Eve his wife; and she conceived, and bare Cain, and said, I have gotten a man from the LORD. 6 | 7 | 2 And she again bare his brother Abel. And Abel was a keeper of sheep, but Cain was a tiller of the ground. 8 | 9 | 3 And in process of time it came to pass, that Cain brought of the fruit of the ground an offering unto the LORD. 10 | 11 | 4 And Abel, he also brought of the firstlings of his flock and of the fat thereof. And the LORD had respect unto Abel and to his offering: 12 | 13 | 5 But unto Cain and to his offering he had not respect. And Cain was very wroth, and his countenance fell. 14 | 15 | 6 And the LORD said unto Cain, Why art thou wroth? and why is thy countenance fallen? 16 | 17 | 7 If thou doest well, shalt thou not be accepted? and if thou doest not well, sin lieth at the door. And unto thee shall be his desire, and thou shalt rule over him. 18 | 19 | 8 And Cain talked with Abel his brother: and it came to pass, when they were in the field, that Cain rose up against Abel his brother, and slew him. 20 | 21 | 9 And the LORD said unto Cain, Where is Abel thy brother? And he said, I know not: Am I my brother's keeper? 22 | 23 | 10 And he said, What hast thou done? the voice of thy brother's blood crieth unto me from the ground. 24 | 25 | 11 And now art thou cursed from the earth, which hath opened her mouth to receive thy brother's blood from thy hand; 26 | 27 | 12 When thou tillest the ground, it shall not henceforth yield unto thee her strength; a fugitive and a vagabond shalt thou be in the earth. 28 | 29 | 13 And Cain said unto the LORD, My punishment is greater than I can bear. 30 | 31 | 14 Behold, thou hast driven me out this day from the face of the earth; and from thy face shall I be hid; and I shall be a fugitive and a vagabond in the earth; and it shall come to pass, that every one that findeth me shall slay me. 32 | 33 | 15 And the LORD said unto him, Therefore whosoever slayeth Cain, vengeance shall be taken on him sevenfold. And the LORD set a mark upon Cain, lest any finding him should kill him. 34 | 35 | 16 And Cain went out from the presence of the LORD, and dwelt in the land of Nod, on the east of Eden. 36 | """ 37 | -------------------------------------------------------------------------------- /extra/dsys/compdec.py: -------------------------------------------------------------------------------- 1 | import zlib 2 | 3 | 4 | Example_Data = """[{"name":"FaceAngleX","addedBy":"VTube Studio","value":45.78,"min":-30,"max":30,"defaultValue":0},{"name":"FacePositionX","addedBy":"VTube Studio","value":8.33,"min":-10,"max":10,"defaultValue":0},{"name":"FaceAngleY","addedBy":"VTube Studio","value":32.78,"min":-30,"max":30,"defaultValue":0},{"name":"FacePositionY","addedBy":"VTube Studio","value":48.33,"min":-10,"max":10,"defaultValue":0},{"name":"FaceAngleZ","addedBy":"VTube Studio","value":32.78,"min":-30,"max":30,"defaultValue":0},{"name":"FacePositionZ","addedBy":"VTube Studio","value":48.33,"min":-10,"max":10,"defaultValue":0},{"name":"LeftEye","addedBy":"VTube Studio","value":79.33,"min":0,"max":100,"defaultValue":0},{"name":"RightEye","addedBy":"VTube Studio","value":79.33,"min":0,"max":100,"defaultValue":0},{"name":"MouthOpen","addedBy":"VTube Studio","value":57.1633,"min":0,"max":100,"defaultValue":0}]""" 5 | 6 | 7 | def compress(data: str): 8 | raw_bytes = data.encode("utf-8") 9 | return zlib.compress(raw_bytes, level=9) 10 | 11 | 12 | def decompress(data: bytes): 13 | return zlib.decompress(data).decode("utf-8") 14 | -------------------------------------------------------------------------------- /extra/dsys/dsys.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/dsys/dsys.ico -------------------------------------------------------------------------------- /extra/dsys/dsys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/dsys/dsys.png -------------------------------------------------------------------------------- /extra/dsys/dsys_128px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/dsys/dsys_128px.png -------------------------------------------------------------------------------- /extra/dsys/main.py: -------------------------------------------------------------------------------- 1 | from ui import MainWindow 2 | from tkinter import ttk 3 | from async_tkinter_loop import async_mainloop 4 | 5 | 6 | def main(): 7 | w = MainWindow() 8 | s = ttk.Style() 9 | s.theme_use('default') 10 | s.configure('.', font=('fixedsys', 10)) 11 | async_mainloop(w) 12 | 13 | 14 | if __name__ == "__main__": 15 | try: 16 | import ctypes 17 | ctypes.windll.shcore.SetProcessDpiAwareness(1) 18 | except Exception as e: 19 | pass 20 | finally: 21 | pass 22 | 23 | main() 24 | -------------------------------------------------------------------------------- /extra/dsys/requirements.txt: -------------------------------------------------------------------------------- 1 | altgraph==0.17.3 2 | async-tkinter-loop==0.7.0 3 | asyncio==3.4.3 4 | pefile==2023.2.7 5 | pyinstaller==5.10.0 6 | pyinstaller-hooks-contrib==2023.2 7 | pywin32-ctypes==0.2.0 8 | websockets==11.0.1 -------------------------------------------------------------------------------- /extra/dsys/resc/apdisconnect.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/dsys/resc/apdisconnect.wav -------------------------------------------------------------------------------- /extra/dsys/resc/masterwarn.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/extra/dsys/resc/masterwarn.wav -------------------------------------------------------------------------------- /extra/dsys/tckdcmprs.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from bin_rw import read_binseq 3 | from compdec import decompress 4 | 5 | if __name__ == "__main__": 6 | if len(sys.argv) != 2: 7 | print("usage: python tckdcmprs.py ", file=sys.stderr) 8 | exit(-1) 9 | 10 | try: 11 | with open(sys.argv[1], "rb") as f_in, open(sys.argv[1] + ".dec", "w") as f_out: 12 | while True: 13 | data = read_binseq(f_in) 14 | if data is None: 15 | break 16 | data = decompress(data) 17 | f_out.write(data + "\n") 18 | except Exception as e: 19 | print(" *** ERROR: %s: %s" % (e.__class__.__name__, e), file=sys.stderr) 20 | sys.exit(1) 21 | -------------------------------------------------------------------------------- /extra/dsys/test_compdec.py: -------------------------------------------------------------------------------- 1 | from compdec import * 2 | import time 3 | 4 | start_time = time.time() 5 | compressed = compress(Example_Data) 6 | end_time = time.time() 7 | 8 | print("Compressed %d -> %d bytes in %f seconds" % (len(Example_Data), len(compressed), end_time - start_time)) -------------------------------------------------------------------------------- /extra/dsys/util.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | 4 | def json_stringify(obj): 5 | return json.dumps(obj, separators=(',', ':')) -------------------------------------------------------------------------------- /extra/dsys/version.txt: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(0, 1, 0, 0), 4 | prodvers=(0, 1, 0, 0), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u'7th General Design Group'), 18 | StringStruct(u'FileDescription', u'Project-WG Dummy System Main Executable'), 19 | StringStruct(u'FileVersion', u'PROTOTYPE - 01'), 20 | StringStruct(u'InternalName', u'dsys'), 21 | StringStruct(u'LegalCopyright', u'Copyright (C) 2022-2023 Chuigda'), 22 | StringStruct(u'OriginalFilename', u'dsys.exe'), 23 | StringStruct(u'ProductName', u'Project-WG Dummy System'), 24 | StringStruct(u'ProductVersion', u'PROTOTYPE - 01')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) -------------------------------------------------------------------------------- /include/GlobalConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_GLOBAL_CONFIG_H 2 | #define PROJECT_WG_GLOBAL_CONFIG_H 3 | 4 | #include 5 | 6 | namespace cw { 7 | 8 | struct GlobalConfig { 9 | bool stayOnTop = false; 10 | bool fillBackground = false; 11 | glm::vec3 backgroundColor { 0.0, 0.0, 0.0 }; 12 | 13 | bool multisampling = true; 14 | int multisamplingSamples = 8; 15 | bool lineSmoothHint = true; 16 | bool anisotropyFilter = true; 17 | bool linearSampling = true; 18 | 19 | enum class ControlMode { 20 | None, 21 | VTS, 22 | OSF, 23 | MP, 24 | Manual 25 | }; 26 | ControlMode defaultControlMode = ControlMode::None; 27 | 28 | int vtsWebsocketPort = 8001; 29 | 30 | int osfUdpPort = 11573; 31 | float osfCorrectionX = 0; 32 | float osfCorrectionY = 0; 33 | float osfCorrectionZ = 0; 34 | int osfSmooth = 8; 35 | 36 | static GlobalConfig Instance; 37 | static char const* ControlModeToString(ControlMode mode); 38 | }; 39 | 40 | void InitGlobalConfig(); 41 | 42 | } // namespace cw 43 | 44 | #endif // PROJECT_WG_GLOBAL_CONFIG_H 45 | -------------------------------------------------------------------------------- /include/Version.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_VERSION_H 2 | #define PROJECT_WG_VERSION_H 3 | 4 | #define WG_PRODUCT_NAME "Project-WG" 5 | #define WG_PRODUCT_VERSION 0,4,0,0 6 | #define WG_PRODUCT_VERSION_STRING "0.4.0.0" 7 | 8 | #define CWGLX_FILE_VERSION 0,4,0,0 9 | #define CWGLX_FILE_VERSION_STRING "0.4.0.0" 10 | 11 | #define CWUTIL_FILE_VERSION 0,4,0,0 12 | #define CWUTIL_FILE_VERSION_STRING "0.4.0.0" 13 | 14 | #define PHONG_TESTER_VERSION 0,4,0,0 15 | #define PHONG_TESTER_VERSION_STRING "0.4.0.0" 16 | 17 | #ifdef CW_WIN32_RESOURCE 18 | #define COMPANY_NAME "7th General Design Group" 19 | #define COPYRIGHT_INFO "Copyright (C) 2022-2023 Chuigda" 20 | #endif // CW_WIN32_RESOURCE 21 | 22 | #endif // PROJECT_WG_VERSION_H 23 | -------------------------------------------------------------------------------- /include/cwglx/Base/ElementBufferObject.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_ELEMENT_BUFFER_OBJECT_H 2 | #define PROJECT_GL2_ELEMENT_BUFFER_OBJECT_H 3 | 4 | #include "cwglx/GL/GL.h" 5 | #include "util/Derive.h" 6 | 7 | namespace cw { 8 | 9 | class ElementBufferObject final { 10 | public: 11 | explicit ElementBufferObject(GLFunctions *f); 12 | ~ElementBufferObject(); 13 | 14 | void Bind(GLFunctions *f) const noexcept; 15 | void Unbind(GLFunctions *f) const noexcept; 16 | 17 | void BufferData(GLFunctions *f, 18 | const GLuint *data, 19 | std::size_t size, 20 | GLenum drawHint = GL_STATIC_DRAW) const noexcept; 21 | 22 | void Delete(GLFunctions *f); 23 | 24 | CW_DERIVE_UNCOPYABLE(ElementBufferObject) 25 | CW_DERIVE_UNMOVABLE(ElementBufferObject) 26 | 27 | private: 28 | GLuint m_EBO; 29 | bool m_Deleted; 30 | }; 31 | 32 | } // namespace cw 33 | 34 | #endif // PROJECT_GL2_ELEMENT_BUFFER_OBJECT_H 35 | -------------------------------------------------------------------------------- /include/cwglx/Base/Shader.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_CWGLX_SHADER_PROGRAM_H 2 | #define PROJECT_GL2_CWGLX_SHADER_PROGRAM_H 3 | 4 | #include 5 | #include "include/cwglx/GL/GL.h" 6 | #include "util/Derive.h" 7 | 8 | namespace cw { 9 | 10 | class Shader { 11 | public: 12 | Shader(QString programText, GLenum shaderType); 13 | 14 | ~Shader(); 15 | 16 | bool Compile(GLFunctions *f); 17 | 18 | void Delete(GLFunctions *f); 19 | 20 | [[nodiscard]] QString GetCompileError() const; 21 | 22 | [[nodiscard]] bool IsReady() const; 23 | 24 | [[nodiscard]] GLuint GetShaderId() const; 25 | 26 | CW_DERIVE_UNCOPYABLE(Shader) 27 | CW_DERIVE_UNMOVABLE(Shader) 28 | 29 | private: 30 | QString m_ProgramText; 31 | GLenum m_ShaderType; 32 | GLuint m_ShaderId; 33 | 34 | bool m_Compiled; 35 | QString m_CompileError; 36 | }; 37 | 38 | } // namespace cw 39 | 40 | #endif // PROJECT_GL2_CWGLX_SHADER_PROGRAM_H 41 | -------------------------------------------------------------------------------- /include/cwglx/Base/ShaderProgram.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_SHADER_PROGRAM_H 2 | #define PROJECT_GL2_SHADER_PROGRAM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "include/cwglx/GL/GL.h" 8 | #include "util/Derive.h" 9 | 10 | namespace cw { 11 | 12 | class Shader; 13 | 14 | class ShaderProgram { 15 | public: 16 | ShaderProgram(); 17 | 18 | ~ShaderProgram(); 19 | 20 | void InitCompilation(GLFunctions *f); 21 | 22 | void AttachShader(GLFunctions *f, Shader *shader); 23 | 24 | bool Link(GLFunctions *f); 25 | 26 | void UseProgram(GLFunctions *f) const; 27 | 28 | void Delete(GLFunctions *f); 29 | 30 | [[nodiscard]] QString GetCompileError() const; 31 | 32 | GLint GetUniformLocation(GLFunctions *f, QString const& uniformName) const; 33 | 34 | void SetUniform(GLFunctions *f, QString const& uniformName, GLint value); 35 | 36 | void SetUniform(GLFunctions *f, QString const& uniformName, GLuint value); 37 | 38 | void SetUniform(GLFunctions *f, QString const& uniformName, GLfloat value); 39 | 40 | void SetUniform(GLFunctions *f, QString const& uniformName, glm::vec3 const& value); 41 | 42 | void SetUniform(GLFunctions *f, QString const& uniformName, glm::vec4 const& value); 43 | 44 | void SetUniform(GLFunctions *f, QString const& uniformName, glm::mat4 const& value); 45 | 46 | void SetUniform3fv(GLFunctions *f, QString const& uniformName, GLfloat const* value); 47 | 48 | void SetUniform4fv(GLFunctions *f, QString const& uniformName, GLfloat const* value); 49 | 50 | void SetUniformMatrix4fv(GLFunctions *f, QString const& uniformName, GLfloat const* value); 51 | 52 | CW_DERIVE_UNCOPYABLE(ShaderProgram) 53 | CW_DERIVE_UNMOVABLE(ShaderProgram) 54 | 55 | private: 56 | GLuint m_ProgramId; 57 | 58 | bool m_Initialised; 59 | bool m_Linked; 60 | QString m_CompileError; 61 | 62 | mutable QMap m_CachedUniforms; 63 | }; 64 | 65 | } // namespace cw 66 | 67 | #endif // PROJECT_GL2_SHADER_PROGRAM_H 68 | -------------------------------------------------------------------------------- /include/cwglx/Base/Texture.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_TEXTURE_H 2 | #define PROJECT_GL2_TEXTURE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "include/cwglx/GL/GL.h" 8 | #include "util/Derive.h" 9 | 10 | class QImage; 11 | 12 | namespace cw { 13 | 14 | class Texture2D { 15 | public: 16 | Texture2D(const QImage &image, 17 | GLFunctions *f, 18 | bool linearSampling, 19 | bool anisotropyFilter); 20 | 21 | [[nodiscard]] GLuint GetTextureId() const noexcept; 22 | 23 | void ActivateTexture(GLFunctions *f, 24 | GLenum textureUnit = GL_TEXTURE0, 25 | GLint uniform = -1) const noexcept; 26 | 27 | void Delete(GLFunctions *f) noexcept; 28 | 29 | ~Texture2D() noexcept; 30 | 31 | CW_DERIVE_UNCOPYABLE(Texture2D) 32 | CW_DERIVE_UNMOVABLE(Texture2D) 33 | 34 | private: 35 | GLuint m_TextureId; 36 | bool m_IsDeleted; 37 | }; 38 | 39 | } // namespace cw 40 | 41 | #endif //PROJECT_GL2_TEXTURE_H 42 | -------------------------------------------------------------------------------- /include/cwglx/Base/VBOImpl/GLM.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_GLM_H 2 | #define PROJECT_GL2_GLM_H 3 | 4 | #include 5 | #include "include/cwglx/GL/GL.h" 6 | #include "util/Wife.h" 7 | 8 | namespace cw::impl { 9 | 10 | template struct VFDProbe; 11 | 12 | template<> struct VFDProbe { 13 | static constexpr GLenum GLTypeEnum = GL_FLOAT; 14 | static constexpr std::size_t ComponentCount = 1; 15 | }; 16 | 17 | template<> struct VFDProbe { 18 | static constexpr GLenum GLTypeEnum = GL_FLOAT; 19 | static constexpr std::size_t ComponentCount = 2; 20 | }; 21 | 22 | template<> struct VFDProbe { 23 | static constexpr GLenum GLTypeEnum = GL_FLOAT; 24 | static constexpr std::size_t ComponentCount = 3; 25 | }; 26 | 27 | template<> struct VFDProbe { 28 | static constexpr GLenum GLTypeEnum = GL_FLOAT; 29 | static constexpr std::size_t ComponentCount = 4; 30 | }; 31 | 32 | } // namespace cw::impl 33 | 34 | #endif // PROJECT_GL2_GLM_H 35 | -------------------------------------------------------------------------------- /include/cwglx/Base/VertexArrayObject.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_VAO_H 2 | #define PROJECT_GL2_VAO_H 3 | 4 | #include 5 | #include 6 | #include "include/cwglx/GL/GL.h" 7 | #include "util/Sinkrate.h" 8 | #include "util/Derive.h" 9 | 10 | namespace cw { 11 | 12 | class VertexArrayObject { 13 | public: 14 | explicit VertexArrayObject(GLFunctions *f); 15 | 16 | VertexArrayObject(GLuint vao, Sinkrate); 17 | 18 | ~VertexArrayObject(); 19 | 20 | void Bind(GLFunctions *f) const; 21 | 22 | void Unbind(GLFunctions *f) const; 23 | 24 | void Delete(GLFunctions *f); 25 | 26 | static std::vector> 27 | CreateMany(GLFunctions *f, GLsizei count); 28 | 29 | CW_DERIVE_UNCOPYABLE(VertexArrayObject) 30 | CW_DERIVE_UNMOVABLE(VertexArrayObject) 31 | 32 | private: 33 | GLuint m_VAO; 34 | bool m_Deleted; 35 | }; 36 | 37 | } 38 | 39 | #endif // PROJECT_GL2_VAO_H 40 | -------------------------------------------------------------------------------- /include/cwglx/Base/VertexBufferObject.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_VBO_H 2 | #define PROJECT_GL2_VBO_H 3 | 4 | #include 5 | #include "include/cwglx/GL/GL.h" 6 | #include "util/Wife.h" 7 | #include "util/Derive.h" 8 | 9 | namespace cw { 10 | 11 | template 12 | class VertexBufferObject { 13 | public: 14 | explicit VertexBufferObject(GLFunctions *f); 15 | 16 | ~VertexBufferObject(); 17 | 18 | void BufferData(GLFunctions *f, 19 | T const* data, 20 | std::size_t count, 21 | GLenum drawHint = GL_STATIC_DRAW); 22 | 23 | void Bind(GLFunctions *f, GLuint baseIndex = 0) const; 24 | 25 | void Unbind(GLFunctions *f) const; 26 | 27 | void Delete(GLFunctions *f); 28 | 29 | CW_DERIVE_UNCOPYABLE(VertexBufferObject) 30 | CW_DERIVE_UNMOVABLE(VertexBufferObject) 31 | 32 | private: 33 | GLuint m_VBO; 34 | bool m_Deleted; 35 | }; 36 | 37 | namespace impl { 38 | template 39 | struct VertexFieldDescriptor { 40 | static constexpr GLenum GLTypeEnum = GLTypeEnum_; 41 | static constexpr std::size_t Offset = Offset_; 42 | static constexpr std::size_t ComponentCount = ComponentCount_; 43 | }; 44 | 45 | template constexpr inline GLenum GetGLTypeEnum(); 46 | 47 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_BYTE; } 48 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_UNSIGNED_BYTE; } 49 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_INT; } 50 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_UNSIGNED_INT; } 51 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_FLOAT; } 52 | template<> constexpr inline GLenum GetGLTypeEnum() { return GL_DOUBLE; } 53 | 54 | // GLboolean == GLubyte, no need of defining that again 55 | // template<> constexpr inline GLenum GetGLTypeEnum() { return GL_BOOL; } 56 | 57 | template 58 | struct VFDProbe {}; 59 | 60 | template 61 | struct VFDProbe> { 62 | static constexpr GLenum GLTypeEnum = GetGLTypeEnum(); 63 | static constexpr std::size_t ComponentCount = N; 64 | }; 65 | 66 | template 67 | struct VFDProbe { 68 | static constexpr GLenum GLTypeEnum = GetGLTypeEnum(); 69 | static constexpr std::size_t ComponentCount = N; 70 | }; 71 | 72 | } // namespace impl 73 | } // namespace cw 74 | 75 | #define CW_IMPL_VFD_PROBE(T, FIELD) \ 76 | cw::impl::VertexFieldDescriptor< \ 77 | offsetof(T, FIELD), \ 78 | cw::impl::VFDProbe().FIELD)>::GLTypeEnum, \ 79 | cw::impl::VFDProbe().FIELD)>::ComponentCount \ 80 | > 81 | 82 | #define CW_IMPL_DEFINE_VBO_TYPE1(T, F1) \ 83 | cw::VertexBufferObject< \ 84 | T, \ 85 | CW_IMPL_VFD_PROBE(T, F1) \ 86 | > 87 | 88 | #define CW_IMPL_DEFINE_VBO_TYPE2(T, F1, F2) \ 89 | cw::VertexBufferObject< \ 90 | T, \ 91 | CW_IMPL_VFD_PROBE(T, F1), \ 92 | CW_IMPL_VFD_PROBE(T, F2) \ 93 | > 94 | 95 | #define CW_IMPL_DEFINE_VBO_TYPE3(T, F1, F2, F3) \ 96 | cw::VertexBufferObject< \ 97 | T, \ 98 | CW_IMPL_VFD_PROBE(T, F1), \ 99 | CW_IMPL_VFD_PROBE(T, F2), \ 100 | CW_IMPL_VFD_PROBE(T, F3) \ 101 | > 102 | 103 | #define CW_IMPL_DEFINE_VBO_TYPE4(T, F1, F2, F3, F4) \ 104 | cw::VertexBufferObject< \ 105 | T, \ 106 | CW_IMPL_VFD_PROBE(T, F1), \ 107 | CW_IMPL_VFD_PROBE(T, F2), \ 108 | CW_IMPL_VFD_PROBE(T, F3), \ 109 | CW_IMPL_VFD_PROBE(T, F4) \ 110 | > 111 | 112 | #define CW_IMPL_DEFINE_VBO_TYPE5(T, F1, F2, F3, F4, F5) \ 113 | cw::VertexBufferObject< \ 114 | T, \ 115 | CW_IMPL_VFD_PROBE(T, F1), \ 116 | CW_IMPL_VFD_PROBE(T, F2), \ 117 | CW_IMPL_VFD_PROBE(T, F3), \ 118 | CW_IMPL_VFD_PROBE(T, F4), \ 119 | CW_IMPL_VFD_PROBE(T, F5) \ 120 | > 121 | 122 | #define CW_IMPL_DEFINE_VBO_TYPE6(T, F1, F2, F3, F4, F5, F6) \ 123 | cw::VertexBufferObject< \ 124 | T, \ 125 | CW_IMPL_VFD_PROBE(T, F1), \ 126 | CW_IMPL_VFD_PROBE(T, F2), \ 127 | CW_IMPL_VFD_PROBE(T, F3), \ 128 | CW_IMPL_VFD_PROBE(T, F4), \ 129 | CW_IMPL_VFD_PROBE(T, F5), \ 130 | CW_IMPL_VFD_PROBE(T, F6) \ 131 | > 132 | 133 | #define CW_IMPL_SELECT_DEFINE_MACRO(_1, _2, _3, _4, _5, _6, _7, NAME, ...) NAME 134 | 135 | #define CW_DEFINE_VBO_TYPE(...) \ 136 | CW_IMPL_SELECT_DEFINE_MACRO( \ 137 | __VA_ARGS__, \ 138 | CW_IMPL_DEFINE_VBO_TYPE6, \ 139 | CW_IMPL_DEFINE_VBO_TYPE5, \ 140 | CW_IMPL_DEFINE_VBO_TYPE4, \ 141 | CW_IMPL_DEFINE_VBO_TYPE3, \ 142 | CW_IMPL_DEFINE_VBO_TYPE2, \ 143 | CW_IMPL_DEFINE_VBO_TYPE1, \ 144 | )(__VA_ARGS__) 145 | 146 | #endif // PROJECT_GL2_VBO_H 147 | -------------------------------------------------------------------------------- /include/cwglx/Base/VertexBufferObjectImpl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_VBO_IMPL_H 2 | #define PROJECT_GL2_VBO_IMPL_H 3 | 4 | #include "VertexBufferObject.h" 5 | #include "include/cwglx/GL/GLImpl.h" 6 | #include "util/Constants.h" 7 | 8 | namespace cw { 9 | namespace impl { 10 | 11 | template 12 | __attribute__((always_inline)) 13 | constexpr inline void BindVBOImpl(GLFunctions*, GLuint) {} 14 | 15 | template 16 | __attribute__((always_inline)) 17 | inline void BindVBOImpl(GLFunctions * f, GLuint baseIndex) { 18 | f->glVertexAttribPointer(N, 19 | VFD::ComponentCount, 20 | VFD::GLTypeEnum, 21 | GL_FALSE, 22 | sizeof(T), 23 | (void*)VFD::Offset); 24 | f->glEnableVertexAttribArray(N); 25 | 26 | BindVBOImpl(f, baseIndex + 1); 27 | } 28 | 29 | } // namespace impl 30 | 31 | template 32 | VertexBufferObject::VertexBufferObject(GLFunctions *f) 33 | : m_VBO(0), 34 | m_Deleted(false) 35 | { 36 | f->glGenBuffers(1, &m_VBO); 37 | } 38 | 39 | template 40 | VertexBufferObject::~VertexBufferObject() { 41 | if (!m_Deleted) { 42 | qWarning() << "VertexBufferObject::~VertexBufferObject():" 43 | << "vertex buffer object deleted before releasing relevant OpenGL resources"; 44 | } 45 | } 46 | 47 | template 48 | void VertexBufferObject::BufferData(GLFunctions *f, 49 | const T *data, 50 | std::size_t count, 51 | GLenum drawHint) 52 | { 53 | if (m_Deleted) { 54 | qWarning() << "VertexBufferObject::Bind(GLFunctions*):" 55 | << "cannot provide data to an already deleted vertex buffer object"; 56 | return; 57 | } 58 | 59 | f->glBufferData(GL_ARRAY_BUFFER, static_cast(sizeof(T) * count), data, drawHint); 60 | } 61 | 62 | template 63 | void VertexBufferObject::Bind(GLFunctions *f, GLuint baseIndex) const { 64 | if (m_Deleted) { 65 | qWarning() << "VertexBufferObject::Bind(GLFunctions*):" 66 | << "cannot bind to an already deleted vertex buffer object"; 67 | return; 68 | } 69 | 70 | f->glBindBuffer(GL_ARRAY_BUFFER, m_VBO); 71 | impl::BindVBOImpl(f, baseIndex); 72 | } 73 | 74 | template 75 | void VertexBufferObject::Unbind(GLFunctions *f) const { 76 | Q_UNUSED(this) 77 | f->glBindBuffer(GL_ARRAY_BUFFER, 0); 78 | } 79 | 80 | template 81 | void VertexBufferObject::Delete(GLFunctions *f) { 82 | if (m_Deleted) { 83 | return; 84 | } 85 | 86 | f->glDeleteBuffers(1, &m_VBO); 87 | m_Deleted = true; 88 | } 89 | 90 | } // namespace cw 91 | 92 | #endif // PROJECT_GL2_VBO_IMPL_H 93 | -------------------------------------------------------------------------------- /include/cwglx/GL/GL.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_CWGLX_GL_H 2 | #define PROJECT_GL2_CWGLX_GL_H 3 | 4 | #include 5 | 6 | class QOpenGLFunctions_3_3_Core; 7 | using GLFunctions = QOpenGLFunctions_3_3_Core; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/cwglx/GL/GLImpl.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /include/cwglx/GL/GLInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_INFO_H 2 | #define PROJECT_GL2_INFO_H 3 | 4 | #include 5 | 6 | #include "cwglx/GL/GL.h" 7 | 8 | namespace cw { 9 | 10 | class GLInfo { 11 | public: 12 | GLInfo(const char *vendor, 13 | const char *version, 14 | const char *renderer, 15 | QString extensions); 16 | 17 | const QString vendor; 18 | const QString version; 19 | const QString renderer; 20 | const QString extensions; 21 | 22 | static GLInfo AutoDetect(GLFunctions *f); 23 | }; 24 | 25 | } // namespace cw 26 | 27 | #endif // PROJECT_GL2_INFO_H 28 | -------------------------------------------------------------------------------- /include/cwglx/Object/Material.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_MATERIAL_H 2 | #define PROJECT_GL2_MATERIAL_H 3 | 4 | #include 5 | #include 6 | #include "cwglx/GL/GL.h" 7 | #include "cwglx/Base/Texture.h" 8 | #include "util/Sinkrate.h" 9 | 10 | namespace cw { 11 | 12 | class GLObjectContext; 13 | 14 | struct Material { 15 | glm::vec4 ambient; 16 | glm::vec4 diffuse; 17 | glm::vec4 specular; 18 | GLfloat shine; 19 | 20 | cw::Texture2D const* diffuseTexture; 21 | cw::Texture2D const* specularTexture; 22 | cw::Texture2D const* normalTexture; 23 | 24 | constexpr inline Material(glm::vec4 const& ambient, 25 | glm::vec4 const& diffuse, 26 | glm::vec4 const& specular, 27 | GLfloat shine, 28 | cw::Texture2D const* diffuseTexture, 29 | cw::Texture2D const* specularTexture, 30 | cw::Texture2D const* normalTexture) 31 | : ambient(ambient), 32 | diffuse(diffuse), 33 | specular(specular), 34 | shine(shine), 35 | diffuseTexture(diffuseTexture), 36 | specularTexture(specularTexture), 37 | normalTexture(normalTexture) 38 | {} 39 | 40 | constexpr inline Material() : Material( 41 | glm::vec4 { 0.0, 0.0, 0.0, 1.0 }, 42 | glm::vec4 { 0.0, 0.0, 0.0, 1.0 }, 43 | glm::vec4 { 0.0, 0.0, 0.0, 1.0 }, 44 | 0.0, 45 | nullptr, 46 | nullptr, 47 | nullptr 48 | ) {} 49 | 50 | CW_DERIVE_UNCOPYABLE(Material) 51 | CW_DERIVE_UNMOVABLE(Material) 52 | }; 53 | 54 | } // namespace cw 55 | 56 | #endif // PROJECT_GL2_MATERIAL_H 57 | -------------------------------------------------------------------------------- /include/cwglx/Object/Object.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_OBJECT_H 2 | #define PROJECT_GL2_OBJECT_H 3 | 4 | #include 5 | #include 6 | #include "cwglx/Object/Material.h" 7 | #include "cwglx/Base/VertexArrayObject.h" 8 | #include "cwglx/Object/Vertex.h" 9 | 10 | namespace cw { 11 | 12 | class ShaderProgram; 13 | 14 | class GLObjectContext final { 15 | public: 16 | GLObjectContext() = default; 17 | ~GLObjectContext() = default; 18 | 19 | void RemoveAll(GLFunctions *f); 20 | void Delete(GLFunctions *f); 21 | 22 | bool HasTexture(QString const& texturePath) const; 23 | bool HasMaterial(QString const& materialName) const; 24 | 25 | Texture2D const* AddTexture(QString texturePath, 26 | std::unique_ptr &&texture); 27 | Material const* AddMaterial(QString materialName, 28 | std::unique_ptr &&material); 29 | 30 | Texture2D const* GetTexture(QString const& texturePath) const; 31 | Material const* GetMaterial(QString const& materialName) const; 32 | 33 | private: 34 | std::unordered_map> m_MaterialLibrary; 35 | std::unordered_map> m_TextureLibrary; 36 | }; 37 | 38 | struct GLObject final { 39 | std::unique_ptr vao; 40 | std::unique_ptr vbo; 41 | GLsizei vertexCount; 42 | Material const* material; 43 | 44 | GLObject(std::unique_ptr &&vao, 45 | std::unique_ptr &&vbo, 46 | GLsizei vertexCount, 47 | Material const* material); 48 | 49 | void Draw(GLFunctions *f, ShaderProgram *shaderProgram) const; 50 | 51 | void Delete(GLFunctions *f) const; 52 | 53 | GLObject(GLObject&&) = default; 54 | GLObject& operator=(GLObject&&) = default; 55 | }; 56 | 57 | } // namespace cw 58 | 59 | #endif // PROJECT_GL2_OBJECT_H 60 | -------------------------------------------------------------------------------- /include/cwglx/Object/Vertex.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_VERTEX_H 2 | #define PROJECT_GL2_VERTEX_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "cwglx/Base/VertexBufferObject.h" 9 | #include "cwglx/Base/VBOImpl/GLM.h" 10 | 11 | namespace cw { 12 | 13 | struct PlainVertex { 14 | glm::vec3 vertexCoord; 15 | }; 16 | 17 | struct SimpleVertex { 18 | glm::vec3 vertexCoord; 19 | glm::vec3 vertexNormal; 20 | }; 21 | 22 | struct Vertex { 23 | glm::vec3 vertexCoord; 24 | glm::vec3 vertexNormal; 25 | glm::vec2 texCoord; 26 | 27 | glm::vec3 tangent; 28 | glm::vec3 biTangent; 29 | }; 30 | 31 | using PlainVertexVBO = CW_DEFINE_VBO_TYPE( 32 | PlainVertex, 33 | vertexCoord 34 | ); 35 | 36 | using SimpleVertexVBO = CW_DEFINE_VBO_TYPE( 37 | SimpleVertex, 38 | vertexCoord, 39 | vertexNormal 40 | ); 41 | 42 | using VertexVBO = CW_DEFINE_VBO_TYPE( 43 | Vertex, 44 | vertexCoord, 45 | vertexNormal, 46 | texCoord, 47 | tangent, 48 | biTangent 49 | ); 50 | 51 | } // namespace cw 52 | 53 | #endif // PROJECT_GL2_VERTEX_H 54 | -------------------------------------------------------------------------------- /include/cwglx/Object/WavefrontLoader.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_WAVEFRONT_LOADER_H 2 | #define PROJECT_GL2_WAVEFRONT_LOADER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cwglx/Object/Object.h" 8 | 9 | namespace cw { 10 | 11 | class GLObjectContext; 12 | 13 | void LoadMaterialLibrary(GLObjectContext *ctx, 14 | GLFunctions *f, 15 | QString const& basePath, 16 | QString const& fileName, 17 | bool linearSampling, 18 | bool anisotropyFilter); 19 | 20 | GLObject LoadObject(GLObjectContext *ctx, 21 | GLFunctions *f, 22 | QString const& basePath, 23 | QString const& fileName, 24 | bool linearSampling, 25 | bool anisotropyFilter, 26 | std::unique_ptr &&vao = nullptr, 27 | std::unique_ptr &&vbo = nullptr); 28 | 29 | } // namespace cw 30 | 31 | #endif // PROJECT_GL2_WAVEFRONT_LOADER_H 32 | -------------------------------------------------------------------------------- /include/cwglx/Setup.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_GL2_SETUP_H 2 | #define PROJECT_GL2_SETUP_H 3 | 4 | #include "include/cwglx/GL/GL.h" 5 | 6 | namespace cw { 7 | 8 | void SetupPreferred(GLFunctions *f); 9 | 10 | } // namespace cw 11 | 12 | #endif // PROJECT_GL2_SETUP_H 13 | -------------------------------------------------------------------------------- /include/ui_next/AttachmentControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_ATTACHMENT_CONTROL_H 2 | #define PROJECT_WG_UINEXT_ATTACHMENT_CONTROL_H 3 | 4 | #include "ui_next/CloseSignallingWidget.h" 5 | #include "wgc0310/api/Attachment.h" 6 | 7 | namespace wgc0310 { 8 | struct AttachmentStatus; 9 | } // namespace wgc0310 10 | 11 | class QMenu; 12 | class QPushButton; 13 | class GLWindow; 14 | struct StatusExtra; 15 | 16 | class AttachmentControl final : public CloseSignallingWidget { 17 | public: 18 | AttachmentControl(wgc0310::AttachmentStatus *attachmentStatus, 19 | GLWindow *glWindow, 20 | StatusExtra *statusExtra); 21 | 22 | private slots: 23 | void ReloadAttachments(); 24 | 25 | private: 26 | void LinkButtonAndContextMenu(QPushButton *button, 27 | QPushButton *configButton, 28 | wgc0310::WGAPIAttachment **attachmentSlot); 29 | void LinkButtonAndControlWidget(QPushButton *button, 30 | wgc0310::WGAPIAttachment **attachment); 31 | 32 | private: 33 | wgc0310::AttachmentStatus *m_AttachmentStatus; 34 | GLWindow *m_GLWindow; 35 | StatusExtra *m_StatusExtra; 36 | 37 | QMenu *m_ItemSelectMenu; 38 | QPushButton *m_RightBigArmAttachment; 39 | QPushButton *m_RightSmallArmAttachment; 40 | QPushButton *m_LeftBigArmAttachment; 41 | QPushButton *m_LeftSmallArmAttachment; 42 | QPushButton *m_RightBigArmConfig; 43 | QPushButton *m_RightSmallArmConfig; 44 | QPushButton *m_LeftBigArmConfig; 45 | QPushButton *m_LeftSmallArmConfig; 46 | QPushButton *m_ReloadButton; 47 | 48 | std::vector> m_Attachments; 49 | std::vector m_SharedObjects; 50 | 51 | QPushButton *m_ActivatedAttachmentButton; 52 | QPushButton *m_ActivatedAttachmentConfigButton; 53 | wgc0310::WGAPIAttachment **m_AttachmentSlot; 54 | }; 55 | 56 | #endif // PROJECT_WG_UINEXT_ATTACHMENT_CONTROL_H 57 | -------------------------------------------------------------------------------- /include/ui_next/BodyControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_BODY_CONTROL_H 2 | #define PROJECT_WG_UINEXT_BODY_CONTROL_H 3 | 4 | #include "wgc0310/BodyStatus.h" 5 | #include "ui_next/CloseSignallingWidget.h" 6 | 7 | class ControlPanel; 8 | class QHBoxLayout; 9 | class QVBoxLayout; 10 | 11 | class BodyControl : public CloseSignallingWidget { 12 | Q_OBJECT 13 | 14 | public: 15 | BodyControl(wgc0310::BodyStatus *bodyStatus, 16 | ControlPanel *controlPanel); 17 | 18 | signals: 19 | #pragma clang diagnostic push 20 | #pragma ide diagnostic ignored "NotImplementedFunctions" 21 | void StartBodyAnimation(); 22 | #pragma clang diagnostic pop 23 | 24 | private: 25 | void ReloadBodyAnimations(); 26 | 27 | wgc0310::BodyStatus *m_BodyStatus; 28 | 29 | QHBoxLayout *m_MinimizedLayout; 30 | QVBoxLayout *m_DetailedLayout; 31 | 32 | std::vector> m_BodyAnimations; 33 | }; 34 | 35 | #endif // PROJECT_WG_UINEXT_BODY_CONTROL_H 36 | -------------------------------------------------------------------------------- /include/ui_next/CloseSignallingWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UI_NEXT_CLOSE_SIGNALLING_WIDGET_H 2 | #define PROJECT_WG_UI_NEXT_CLOSE_SIGNALLING_WIDGET_H 3 | 4 | #include 5 | 6 | class CloseSignallingWidget : public QWidget { 7 | Q_OBJECT 8 | 9 | public: 10 | explicit CloseSignallingWidget(QWidget *parent = nullptr, 11 | Qt::WindowType windowType = Qt::Window) 12 | : QWidget(parent, windowType) 13 | {} 14 | ~CloseSignallingWidget() override = default; 15 | 16 | signals: 17 | #pragma clang diagnostic push 18 | #pragma ide diagnostic ignored "NotImplementedFunctions" 19 | void AboutToHideOrClose(); 20 | void AboutToClose(); 21 | #pragma clang diagnostic pop 22 | 23 | protected: 24 | void closeEvent(QCloseEvent *event) override { 25 | QWidget::closeEvent(event); 26 | emit AboutToHideOrClose(); 27 | emit AboutToClose(); 28 | } 29 | 30 | void hideEvent(QHideEvent *event) override { 31 | QWidget::hideEvent(event); 32 | emit AboutToHideOrClose(); 33 | } 34 | }; 35 | 36 | #endif // PROJECT_WG_UI_NEXT_CLOSE_SIGNALLING_WIDGET_H 37 | -------------------------------------------------------------------------------- /include/ui_next/CodeEdit.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_CODE_EDIT_H 2 | #define PROJECT_WG_UINEXT_CODE_EDIT_H 3 | 4 | #include 5 | 6 | // an editor widget with auto indentation and automatically replaces tabs with FOUR spaces 7 | class CodeEdit final : public QTextEdit { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit CodeEdit(QWidget *parent = nullptr); 12 | ~CodeEdit() final = default; 13 | 14 | // overwrite several events 15 | protected: 16 | void keyPressEvent(QKeyEvent *event) final; 17 | }; 18 | 19 | #endif // PROJECT_WG_UINEXT_CODE_EDIT_H 20 | -------------------------------------------------------------------------------- /include/ui_next/ControlPanel.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_CONTROL_PANEL_H 2 | #define PROJECT_WG_UINEXT_CONTROL_PANEL_H 3 | 4 | #include 5 | #include 6 | #include "wgc0310/ScreenAnimationStatus.h" 7 | #include "wgc0310/HeadStatus.h" 8 | #include "wgc0310/BodyStatus.h" 9 | #include "wgc0310/Shader.h" 10 | #include "wgc0310/AttachmentStatus.h" 11 | #include "ui_next/EntityStatus.h" 12 | #include "ui_next/ExtraControl.h" 13 | #include "util/CircularBuffer.h" 14 | 15 | class QPushButton; 16 | class GLWindow; 17 | class GLInfoDisplay; 18 | class EntityControl; 19 | class TrackControl; 20 | class ScreenAnimationControl; 21 | class BodyControl; 22 | class AttachmentControl; 23 | class SoundControl; 24 | class ShaderEdit; 25 | class HelpBox; 26 | class LicensePresenter; 27 | 28 | class ControlPanel final : public QWidget { 29 | Q_OBJECT 30 | 31 | public: 32 | explicit ControlPanel(bool startHideGL); 33 | ~ControlPanel() noexcept final; 34 | 35 | void DoneSplash(); 36 | 37 | signals: 38 | #pragma clang diagnostic push 39 | #pragma ide diagnostic ignored "NotImplementedFunctions" 40 | void DoneBodyAnimation(); 41 | #pragma clang diagnostic pop 42 | 43 | protected: 44 | void closeEvent(QCloseEvent *e) final; 45 | 46 | private slots: 47 | void NextTick(); 48 | 49 | private: 50 | // Worker thread, must be initialized very first 51 | QThread m_WorkerThread; 52 | 53 | // status 54 | EntityStatus m_EntityStatus; 55 | wgc0310::HeadStatus m_HeadStatus; 56 | wgc0310::ScreenAnimationStatus m_ScreenAnimationStatus; 57 | wgc0310::ScreenDisplayMode m_ScreenDisplayMode; 58 | wgc0310::BodyStatus m_BodyStatus; 59 | wgc0310::AttachmentStatus m_AttachmentStatus; 60 | cw::CircularBuffer m_VolumeLevels; 61 | bool m_VolumeLevelsUpdated; 62 | StatusExtra m_ExtraStatus; 63 | 64 | bool m_StartHideGL; 65 | 66 | // widgets 67 | GLWindow *m_GLWindow; 68 | GLInfoDisplay *m_GLInfoDisplay; 69 | EntityControl *m_EntityControl; 70 | TrackControl *m_TrackControl; 71 | ScreenAnimationControl *m_ScreenAnimationControl; 72 | BodyControl *m_BodyControl; 73 | AttachmentControl *m_AttachmentControl; 74 | SoundControl *m_SoundControl; 75 | ExtraControl *m_ExtraControl; 76 | ShaderEdit *m_ShaderEdit; 77 | HelpBox *m_HelpBox; 78 | 79 | QPushButton *m_OpenGLSettingsButton; 80 | QPushButton *m_CameraSettingsButton; 81 | QPushButton *m_BodyAnimationButton; 82 | QPushButton *m_AttachmentButton; 83 | QPushButton *m_FaceAnimationButton; 84 | QPushButton *m_PoseEstimationButton; 85 | QPushButton *m_VolumeAnalysisButton; 86 | QPushButton *m_ExtraSettingsButton; 87 | QPushButton *m_ShaderEditButton; 88 | QPushButton *m_HelpButton; 89 | }; 90 | 91 | #endif // PROJECT_WG_UINEXT_CONTROL_PANEL_H 92 | -------------------------------------------------------------------------------- /include/ui_next/EntityControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_CAMERA_CONTROL_H 2 | #define PROJECT_WG_UINEXT_CAMERA_CONTROL_H 3 | 4 | #include "ui_next/CloseSignallingWidget.h" 5 | 6 | class EntityStatus; 7 | 8 | class EntityControl : public CloseSignallingWidget { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit EntityControl(EntityStatus *status) noexcept; 13 | 14 | signals: 15 | #pragma clang diagnostic push 16 | #pragma ide diagnostic ignored "NotImplementedFunctions" 17 | void ResetEntityStatus(); 18 | #pragma clang diagnostic pop 19 | 20 | private: 21 | EntityStatus *m_EntityStatus; 22 | }; 23 | 24 | #endif // PROJECT_WG_UINEXT_CAMERA_CONTROL_H 25 | -------------------------------------------------------------------------------- /include/ui_next/EntityStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_CAMERA_ENTITY_STATUS_H 2 | #define PROJECT_WG_UINEXT_CAMERA_ENTITY_STATUS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cwglx/GL/GL.h" 9 | 10 | class EntityStatus { 11 | public: 12 | GLfloat translateX; 13 | GLfloat translateY; 14 | GLfloat translateZ; 15 | 16 | GLfloat entityRotateX; 17 | GLfloat entityRotateY; 18 | GLfloat entityRotateZ; 19 | 20 | explicit constexpr inline EntityStatus() noexcept 21 | : translateX(0.0f), 22 | translateY(25.0f), 23 | translateZ(75.0f), 24 | entityRotateX(0.0f), 25 | entityRotateY(0.0f), 26 | entityRotateZ(0.0f) 27 | {} 28 | 29 | constexpr void Reset() noexcept { 30 | *this = EntityStatus {}; 31 | } 32 | 33 | void ToMatrix(glm::mat4 &matrix) const noexcept { 34 | matrix = glm::translate(matrix, glm::vec3(-translateX, -translateY, -translateZ)); 35 | matrix = glm::rotate(matrix, glm::radians(entityRotateX), glm::vec3(1.0f, 0.0f, 0.0f)); 36 | matrix = glm::rotate(matrix, glm::radians(entityRotateY), glm::vec3(0.0f, 1.0f, 0.0f)); 37 | matrix = glm::rotate(matrix, glm::radians(entityRotateZ), glm::vec3(0.0f, 0.0f, 1.0f)); 38 | } 39 | }; 40 | 41 | #endif // PROJECT_WG_UINEXT_CAMERA_ENTITY_STATUS_H 42 | -------------------------------------------------------------------------------- /include/ui_next/ExtraControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_EXTRA_CONTROL_H 2 | #define PROJECT_WG_UINEXT_EXTRA_CONTROL_H 3 | 4 | #include 5 | #include "cwglx/GL/GL.h" 6 | #include "ui_next/CloseSignallingWidget.h" 7 | 8 | namespace wgc0310 { 9 | struct ShaderText; 10 | } // namespace wgc0310 11 | 12 | struct StatusExtra { 13 | bool stayOnTop; 14 | 15 | bool customClearColor; 16 | glm::vec4 clearColor { 0.0f, 0.0f, 0.0f, 1.0f }; 17 | }; 18 | 19 | class GLWindow; 20 | class ShaderEdit; 21 | 22 | class ExtraControl final : public CloseSignallingWidget { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit ExtraControl(GLWindow *glWindow, 27 | StatusExtra *statusExtra); 28 | 29 | signals: 30 | #pragma clang diagnostic push 31 | #pragma ide diagnostic ignored "NotImplementedFunctions" 32 | void SetStayOnTop(bool stayOnTop); 33 | #pragma clang diagnostic pop 34 | 35 | private: 36 | GLWindow *m_GLWindow; 37 | StatusExtra *m_StatusExtra; 38 | }; 39 | 40 | #endif // PROJECT_WG_UINEXT_EXTRA_CONTROL_H 41 | -------------------------------------------------------------------------------- /include/ui_next/FaceTrackControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_FACE_TRACK_CONTROL_H 2 | #define PROJECT_WG_FACE_TRACK_CONTROL_H 3 | 4 | #include 5 | #include "ui_next/CloseSignallingWidget.h" 6 | 7 | namespace wgc0310 { 8 | struct HeadStatus; 9 | class BodyStatus; 10 | 11 | enum class ScreenDisplayMode : std::int8_t; 12 | } // namespace wgc0310 13 | 14 | class VTSTrackControl; 15 | class OSFTrackControl; 16 | class ManualTrackControl; 17 | 18 | class TrackControl : public CloseSignallingWidget { 19 | public: 20 | TrackControl(wgc0310::HeadStatus *headStatus, 21 | wgc0310::ScreenDisplayMode *screenDisplayMode, 22 | QThread *workerThread); 23 | 24 | private: 25 | // Output 26 | wgc0310::HeadStatus *m_HeadStatus; 27 | wgc0310::ScreenDisplayMode *m_ScreenDisplayMode; 28 | 29 | // Control widgets 30 | VTSTrackControl *m_VTSTrackControl; 31 | OSFTrackControl *m_OSFTrackControl; 32 | ManualTrackControl *m_ManualTrackControl; 33 | 34 | // Shared worker thread 35 | QThread *m_WorkerThread; 36 | }; 37 | 38 | #endif // PROJECT_WG_FACE_TRACK_CONTROL_H 39 | -------------------------------------------------------------------------------- /include/ui_next/GLInfoDisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_GLINFO_H 2 | #define PROJECT_WG_UINEXT_GLINFO_H 3 | 4 | #include "ui_next/CloseSignallingWidget.h" 5 | 6 | class QLineEdit; 7 | class QPlainTextEdit; 8 | class GLWindow; 9 | class SearchDialog; 10 | 11 | class GLInfoDisplay : public CloseSignallingWidget { 12 | public: 13 | explicit GLInfoDisplay(GLWindow *glWindow); 14 | 15 | private slots: 16 | void LoadGLInfo(); 17 | 18 | private: 19 | GLWindow *m_GLWindow; 20 | 21 | QLineEdit *m_Vendor; 22 | QLineEdit *m_Version; 23 | QLineEdit *m_Renderer; 24 | QPlainTextEdit *m_Extensions; 25 | SearchDialog *m_SearchDialog; 26 | }; 27 | 28 | #endif // PROJECT_WG_UINEXT_GLINFO_H 29 | -------------------------------------------------------------------------------- /include/ui_next/GLWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_GLWINDOW_H 2 | #define PROJECT_WG_UINEXT_GLWINDOW_H 3 | 4 | #include 5 | #include "cwglx/GL/GL.h" 6 | #include "wgc0310/BodyStatus.h" 7 | #include "wgc0310/AttachmentStatus.h" 8 | #include "wgc0310/Screen.h" 9 | #include "wgc0310/Mesh.h" 10 | #include "wgc0310/HeadStatus.h" 11 | #include "wgc0310/ScreenAnimationStatus.h" 12 | #include "wgc0310/Shader.h" 13 | #include "ui_next/EntityStatus.h" 14 | #include "ui_next/ExtraControl.h" 15 | #include "util/CircularBuffer.h" 16 | 17 | class GLWindow final : public QOpenGLWidget { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit GLWindow(EntityStatus const* entityStatus, 22 | wgc0310::HeadStatus const* headStatus, 23 | wgc0310::BodyStatus const* bodyStatus, 24 | wgc0310::AttachmentStatus const* attachmentStatus, 25 | wgc0310::ScreenAnimationStatus const *screenAnimationStatus, 26 | cw::CircularBuffer *volumeLevels, 27 | bool *volumeLevelsUpdated, 28 | wgc0310::ScreenDisplayMode const *screenDisplayMode, 29 | StatusExtra const* statusExtra); 30 | ~GLWindow() final; 31 | 32 | void RunWithGLContext(std::function const& f); 33 | void EnablePerformanceCounter(); 34 | GLuint64 QueryPerformanceCounter(); 35 | 36 | void ReloadModel(); 37 | bool SetShader(std::unique_ptr &&shader); 38 | 39 | // OpenGL function 40 | GLFunctions *GL; 41 | 42 | protected: 43 | void initializeGL() final; 44 | void paintGL() final; 45 | void resizeGL(int w, int h) final; 46 | 47 | signals: 48 | #pragma clang diagnostic push 49 | #pragma ide diagnostic ignored "NotImplementedFunctions" 50 | void OpenGLInitialized(); 51 | #pragma clang diagnostic pop 52 | 53 | private: 54 | void DrawScreenContent(); 55 | 56 | private: 57 | // Internal status 58 | qreal m_DevicePixelRatio; 59 | 60 | // Input status 61 | EntityStatus const* m_EntityStatus; 62 | wgc0310::HeadStatus const* m_HeadStatus; 63 | wgc0310::BodyStatus const* m_BodyStatus; 64 | wgc0310::AttachmentStatus const* m_AttachmentStatus; 65 | wgc0310::ScreenAnimationStatus const *m_ScreenAnimationStatus; 66 | cw::CircularBuffer *m_VolumeLevels; 67 | bool *m_VolumeLevelsUpdated; 68 | wgc0310::ScreenDisplayMode const *m_ScreenDisplayMode; 69 | 70 | StatusExtra const* m_StatusExtra; 71 | 72 | cw::GLObjectContext m_GLObjectContext; 73 | std::unique_ptr m_Shader; 74 | std::unique_ptr m_Screen; 75 | std::unique_ptr m_Model; 76 | 77 | glm::mat4 m_Projection; 78 | 79 | GLuint m_PerformanceCounter; 80 | bool m_PerformanceCounterEnabled; 81 | }; 82 | 83 | #endif // PROJECT_WG_UINEXT_GLWINDOW_H 84 | -------------------------------------------------------------------------------- /include/ui_next/HelpBox.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_HELPBOX_H 2 | #define PROJECT_WG_UINEXT_HELPBOX_H 3 | 4 | #include "CloseSignallingWidget.h" 5 | 6 | class HelpBox final : public CloseSignallingWidget { 7 | public: 8 | explicit HelpBox(QWidget *parent = nullptr); 9 | }; 10 | 11 | #endif // PROJECT_WG_UINEXT_HELPBOX_H 12 | -------------------------------------------------------------------------------- /include/ui_next/LicensePresenter.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_LICENSE_PRESENTER_H 2 | #define PROJECT_WG_UINEXT_LICENSE_PRESENTER_H 3 | 4 | #include 5 | #include "util/Derive.h" 6 | 7 | class QLabel; 8 | class QPushButton; 9 | class QPlainTextEdit; 10 | class QGroupBox; 11 | 12 | struct LicenseContent { 13 | LicenseContent(QString const& licenseName, 14 | QString licenseText, 15 | QString const& licenseBrief = "", 16 | QString const& helpLink = ""); 17 | 18 | CW_DERIVE_DEFAULT_COPY(LicenseContent) 19 | 20 | QString licenseName; 21 | QString licenseBrief; 22 | QString licenseText; 23 | QString helpLink; 24 | }; 25 | 26 | class LicensePresenter final : public QDialog { 27 | public: 28 | explicit LicensePresenter(QWidget *parent = nullptr); 29 | 30 | void AddLicense(LicenseContent const& licenseContent); 31 | 32 | void DisplayCurrentLicense(); 33 | 34 | void RequireAgreement(bool required = true); 35 | 36 | void showEvent(QShowEvent *) final; 37 | 38 | private slots: 39 | void PrevLicense(); 40 | 41 | void NextLicense(); 42 | 43 | private: 44 | QList m_Licenses; 45 | qsizetype m_CurrentLicense; 46 | 47 | QLabel *m_LicenseNameLabel; 48 | QPushButton *m_PrevLicenseButton; 49 | QPushButton *m_NextLicenseButton; 50 | QGroupBox *m_BriefGroupBox; 51 | QPlainTextEdit *m_BriefText; 52 | QPlainTextEdit *m_LicenseText; 53 | QLabel *m_LicenseLink; 54 | QPushButton *m_DisagreeButton; 55 | QPushButton *m_AgreeButton; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/ui_next/ScreenAnimationControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_SCREEN_ANIMATION_CONTROL_H 2 | #define PROJECT_WG_UINEXT_SCREEN_ANIMATION_CONTROL_H 3 | 4 | #include 5 | #include 6 | 7 | #include "wgc0310/HeadStatus.h" 8 | #include "wgc0310/ScreenAnimationStatus.h" 9 | #include "ui_next/CloseSignallingWidget.h" 10 | 11 | class GLWindow; 12 | class QHBoxLayout; 13 | class QVBoxLayout; 14 | class QRadioButton; 15 | struct StatusExtra; 16 | 17 | class ScreenAnimationControl : public CloseSignallingWidget { 18 | public: 19 | ScreenAnimationControl(GLWindow *glWindow, 20 | wgc0310::ScreenAnimationStatus *animationStatus, 21 | wgc0310::ScreenDisplayMode *screenDisplayMode, 22 | StatusExtra *statusExtra); 23 | 24 | public slots: 25 | void GLContextReady(); 26 | 27 | private: 28 | void ReloadStaticImages(); 29 | void ReloadScreenAnimations(); 30 | 31 | private: 32 | GLWindow *m_GLWindow; 33 | wgc0310::ScreenAnimationStatus *m_ScreenAnimationStatus; 34 | wgc0310::ScreenDisplayMode *m_ScreenDisplayMode; 35 | StatusExtra *m_StatusExtra; 36 | 37 | std::vector m_StaticImages; 38 | std::vector> m_ScreenAnimations; 39 | std::vector m_SharedObjects; 40 | 41 | QHBoxLayout *m_StaticImageButtonsLayout; 42 | QVBoxLayout *m_StaticImageButtonsLayoutV; 43 | 44 | QHBoxLayout *m_ScreenAnimationButtonsLayout; 45 | QVBoxLayout *m_ScreenAnimationButtonsLayoutV; 46 | 47 | QRadioButton *m_PlayingCapturedExpression; 48 | QRadioButton *m_PlayingSoundWave; 49 | QRadioButton *m_PlayingStaticImage; 50 | QRadioButton *m_PlayingDynamicAnimation; 51 | }; 52 | 53 | #endif // PROJECT_WG_UINEXT_SCREEN_ANIMATION_CONTROL_H 54 | -------------------------------------------------------------------------------- /include/ui_next/SearchDialog.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_SEARCH_DIALOG_H 2 | #define PROJECT_WG_UINEXT_SEARCH_DIALOG_H 3 | 4 | #include 5 | #include "CloseSignallingWidget.h" 6 | 7 | class QPlainTextEdit; 8 | 9 | class SearchDialog : public QWidget { 10 | Q_OBJECT 11 | public: 12 | explicit SearchDialog(QPlainTextEdit *plainTextEdit, 13 | CloseSignallingWidget *parent = nullptr); 14 | 15 | private: 16 | QPlainTextEdit *m_TextEdit; 17 | }; 18 | 19 | #endif // PROJECT_WG_UINEXT_SEARCH_DIALOG_H 20 | -------------------------------------------------------------------------------- /include/ui_next/ShaderEdit.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_SHADER_EDIT_H 2 | #define PROJECT_WG_SHADER_EDIT_H 3 | 4 | #include 5 | #include "wgc0310/Shader.h" 6 | #include "ui_next/CloseSignallingWidget.h" 7 | 8 | namespace wgc0310 { 9 | struct ShaderText; 10 | } // namespace wgc0310 11 | 12 | class GLWindow; 13 | 14 | class ShaderEdit : public CloseSignallingWidget { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ShaderEdit(GLWindow *glWindow); 19 | 20 | private: 21 | wgc0310::ShaderText m_ShaderText; 22 | GLWindow *m_GLWindow; 23 | 24 | int m_ShaderPrevIndex; 25 | int m_ShaderSubPrevIndex; 26 | }; 27 | 28 | #endif // PROJECT_WG_SHADER_EDIT_H 29 | -------------------------------------------------------------------------------- /include/ui_next/ShaderHighlighter.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_SHADER_HIGHLIGHT_H 2 | #define PROJECT_WG_UINEXT_SHADER_HIGHLIGHT_H 3 | 4 | #include 5 | #include 6 | 7 | class ShaderHighlighter : public QSyntaxHighlighter { 8 | Q_OBJECT 9 | 10 | public: 11 | explicit ShaderHighlighter(QTextDocument *parent = nullptr); 12 | 13 | protected: 14 | void highlightBlock(const QString &text) override; 15 | 16 | private: 17 | struct HighlightingRule { 18 | QRegularExpression pattern; 19 | QTextCharFormat format; 20 | }; 21 | QList highlightingRules; 22 | 23 | QRegularExpression commentStartExpression; 24 | QRegularExpression commentEndExpression; 25 | 26 | QTextCharFormat pragmaFormat; 27 | QTextCharFormat keywordFormat; 28 | QTextCharFormat typeFormat; 29 | QTextCharFormat functionFormat; 30 | QTextCharFormat builtinVarFormat; 31 | QTextCharFormat singleLineCommentFormat; 32 | QTextCharFormat multiLineCommentFormat; 33 | }; 34 | 35 | #endif // PROJECT_WG_UINEXT_SHADER_HIGHLIGHT_H 36 | -------------------------------------------------------------------------------- /include/ui_next/SoundControl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_SOUND_CONTROL_H 2 | #define PROJECT_WG_SOUND_CONTROL_H 3 | 4 | #include 5 | #include 6 | 7 | #include "ui_next/CloseSignallingWidget.h" 8 | #include "util/CircularBuffer.h" 9 | 10 | class QMediaDevices; 11 | class QComboBox; 12 | class QProgressBar; 13 | 14 | class SoundControl : public CloseSignallingWidget { 15 | Q_OBJECT 16 | 17 | public: 18 | SoundControl(cw::CircularBuffer *volumeLevels, 19 | bool *volumeLevelsUpdated, 20 | QThread *workerThread); 21 | 22 | signals: 23 | #pragma clang diagnostic push 24 | #pragma ide diagnostic ignored "NotImplementedFunctions" 25 | void StartAnalysis(QAudioDevice const& device); 26 | void StopAnalysis(); 27 | #pragma clang diagnostic pop 28 | 29 | private slots: 30 | void ReloadAudioDevices(); 31 | void HandleSample(qreal sample); 32 | void HandleError(QString const& reason); 33 | 34 | private: 35 | cw::CircularBuffer *m_VolumeLevels; 36 | bool *m_VolumeLevelsUpdated; 37 | 38 | QComboBox *m_DeviceSelect; 39 | QProgressBar *m_VolumeLevel; 40 | QList m_DetectedAudioDevices; 41 | 42 | QMediaDevices *m_MediaDevices; 43 | QThread *m_WorkerThread; 44 | }; 45 | 46 | #endif // PROJECT_WG_SOUND_CONTROL_H 47 | -------------------------------------------------------------------------------- /include/util/CircularBuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_CIRCULAR_BUFFER_H 2 | #define PROJECT_WG_CIRCULAR_BUFFER_H 3 | 4 | #include 5 | #include 6 | #include "util/Wife.h" 7 | 8 | namespace cw { 9 | 10 | template 11 | class CircularBuffer { 12 | public: 13 | constexpr inline CircularBuffer() : m_First(0), m_Last(0) {} 14 | explicit constexpr inline CircularBuffer(T const& fillValue) 15 | : m_Buffer { fillValue, { N } }, 16 | m_First(0), 17 | m_Last(0) 18 | {} 19 | 20 | [[nodiscard]] constexpr inline std::size_t Size() const noexcept { 21 | if (m_Last > m_First) { 22 | return m_Last - m_First; 23 | } else { 24 | return (N - m_First) + m_Last; 25 | } 26 | } 27 | 28 | [[nodiscard]] constexpr inline T Get(std::size_t idx) const noexcept { 29 | return m_Buffer[(m_First + idx) % N]; 30 | } 31 | 32 | constexpr inline void PushBack(T value) noexcept { 33 | m_Buffer[m_Last] = value; 34 | m_Last = (m_Last + 1) % N; 35 | } 36 | 37 | constexpr inline T PopFront() noexcept { 38 | T r = m_Buffer[m_First]; 39 | m_First = (m_First + 1) % N; 40 | return r; 41 | } 42 | 43 | private: 44 | std::array m_Buffer; 45 | std::size_t m_First; 46 | std::size_t m_Last; 47 | }; 48 | 49 | } // namespace cw 50 | 51 | #endif // PROJECT_WG_CIRCULAR_BUFFER_H 52 | -------------------------------------------------------------------------------- /include/util/Constants.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_CONSTANTS_H 2 | #define PROJECT_WG_CONSTANTS_H 3 | 4 | #include 5 | #include "util/Wife.h" 6 | 7 | namespace cw::constants { 8 | 9 | constexpr double PI = 3.1415926535897932384626433832795; 10 | constexpr double G = 9.81; 11 | 12 | } // namespace cw::constants 13 | 14 | namespace cw { 15 | 16 | constexpr inline double DegToRad(double deg) noexcept { 17 | return deg * constants::PI / 180.0; 18 | } 19 | 20 | constexpr inline double RadToDeg(double rad) noexcept { 21 | return rad * 180.0 / constants::PI; 22 | } 23 | 24 | template 25 | __attribute__((always_inline)) 26 | constexpr inline std::size_t countof(T const (&unused)[N]) noexcept { 27 | (void)unused; 28 | return N; 29 | } 30 | 31 | template 32 | __attribute__((always_inline)) 33 | constexpr inline std::size_t countof(std::array const&) noexcept { 34 | return N; 35 | } 36 | 37 | template 38 | __attribute__((always_inline)) 39 | constexpr inline T FlipEnum(T input) noexcept { 40 | return static_cast(-(static_cast(input))); 41 | } 42 | 43 | } // namespace cw 44 | 45 | #endif // PROJECT_WG_CONSTANTS_H 46 | -------------------------------------------------------------------------------- /include/util/Derive.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_DERIVE_H 2 | #define PROJECT_WG_DERIVE_H 3 | 4 | #define CW_DERIVE_UNCOPYABLE(CLASS) \ 5 | CLASS(const CLASS &) = delete; \ 6 | CLASS &operator=(const CLASS &) = delete; 7 | 8 | #define CW_DERIVE_UNMOVABLE(CLASS) \ 9 | CLASS(CLASS &&) = delete; \ 10 | CLASS &operator=(CLASS &&) = delete; 11 | 12 | #define CW_DERIVE_DEFAULT_COPY(CLASS) \ 13 | CLASS(const CLASS &) = default; \ 14 | CLASS &operator=(const CLASS &) = default; 15 | 16 | #define CW_DERIVE_DEFAULT_MOVE(CLASS) \ 17 | CLASS(CLASS &&) = default; \ 18 | CLASS &operator=(CLASS &&) = default; 19 | 20 | #endif // PROJECT_WG_DERIVE_H 21 | -------------------------------------------------------------------------------- /include/util/DynLoad.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_DYN_LOAD_H 2 | #define PROJECT_WG_DYN_LOAD_H 3 | 4 | #include "util/Wife.h" 5 | 6 | class QString; 7 | 8 | namespace cw { 9 | 10 | void *LoadSharedObject(QString const& fileName); 11 | void *TryReadSymbolImpl(void *handle, const char *funcName); 12 | void DetachSharedObject(void *handle); 13 | 14 | template 15 | T TryReadSymbol(void *handle, const char *funcName) { 16 | return reinterpret_cast(TryReadSymbolImpl(handle, funcName)); 17 | } 18 | 19 | } // namespace cw 20 | 21 | #endif // PROJECT_WG_DYN_LOAD_H 22 | -------------------------------------------------------------------------------- /include/util/FileUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_FILEUTIL_H 2 | #define PROJECT_WG_FILEUTIL_H 3 | 4 | class QString; 5 | 6 | namespace cw { 7 | 8 | bool IsFileExists(QString const& fileName); 9 | 10 | QString ReadToString(QString const &fileName); 11 | 12 | bool WriteToFile(QString const& fileName, QString const& content); 13 | 14 | } // namespace cw 15 | 16 | #endif // PROJECT_WG_FILEUTIL_H 17 | -------------------------------------------------------------------------------- /include/util/IniLoader.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_INI_LOADER_H 2 | #define PROJECT_WG_INI_LOADER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "util/Sinkrate.h" 8 | #include "util/Derive.h" 9 | 10 | namespace cw { 11 | 12 | class IniSection { 13 | friend class IniFileData; 14 | 15 | public: 16 | explicit IniSection(QString sectionName, Sinkrate); 17 | 18 | CW_DERIVE_DEFAULT_COPY(IniSection) 19 | CW_DERIVE_DEFAULT_MOVE(IniSection) 20 | 21 | [[nodiscard]] QString const& GetSectionName() const; 22 | 23 | std::unordered_map const& GetData() const; 24 | 25 | [[nodiscard]] QString GetData(QString const& key, 26 | QString const& defaultValue = QString()) const; 27 | 28 | [[nodiscard]] int GetIntValue(QString const& key, int defaultValue = 0) const; 29 | 30 | [[nodiscard]] float GetFloatValue(QString const& key, float defaultValue = 0.0) const; 31 | 32 | [[nodiscard]] double GetDoubleValue(QString const& key, double defaultValue = 0.0) const; 33 | 34 | [[nodiscard]] bool GetBoolValue(QString const& key, bool defaultValue = false) const; 35 | 36 | private: 37 | void AddData(QString const& key, QString const& value); 38 | 39 | QString m_SectionName; 40 | std::unordered_map m_SectionData; 41 | }; 42 | 43 | class IniFileData { 44 | public: 45 | CW_DERIVE_DEFAULT_COPY(IniFileData) 46 | CW_DERIVE_DEFAULT_MOVE(IniFileData) 47 | 48 | std::unordered_map const& GetData() const; 49 | 50 | [[nodiscard]] IniSection const* GetSection(QString const& sectionName) const; 51 | 52 | [[nodiscard]] QString GetData(QString const& composedKey, 53 | QString const& defaultValue = QString()) const; 54 | 55 | [[nodiscard]] int GetIntValue(QString const& composedKey, int defaultValue = 0) const; 56 | 57 | [[nodiscard]] float GetFloatValue(QString const& composedKey, float defaultValue = 0.0) const; 58 | 59 | [[nodiscard]] double GetDoubleValue(QString const& composedKey, double defaultValue = 0.0) const; 60 | 61 | [[nodiscard]] bool GetBoolValue(QString const& composedKey, bool defaultValue = false) const; 62 | 63 | [[nodiscard]] QString GetDataEx(QString const& sectionName, 64 | QString const& key, 65 | QString const& defaultValue = QString()) const; 66 | 67 | [[nodiscard]] int GetIntValue(QString const& sectionName, 68 | QString const& key, 69 | int defaultValue = 0) const; 70 | 71 | [[nodiscard]] float GetFloatValue(QString const& sectionName, 72 | QString const& key, 73 | float defaultValue = 0.0) const; 74 | 75 | [[nodiscard]] double GetDoubleValue(QString const& sectionName, 76 | QString const& key, 77 | double defaultValue = 0.0) const; 78 | 79 | [[nodiscard]] bool GetBoolValue(QString const& sectionName, 80 | QString const& key, 81 | bool defaultValue = false) const; 82 | 83 | [[nodiscard]] static IniFileData Parse(QString const& data); 84 | 85 | private: 86 | IniFileData() = default; 87 | void AddSection(IniSection&& section); 88 | 89 | std::unordered_map m_Sections; 90 | }; 91 | 92 | } // namespace cw 93 | 94 | #endif // PROJECT_WG_INI_LOADER_H 95 | -------------------------------------------------------------------------------- /include/util/Sinkrate.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_SINKRATE_H 2 | #define PROJECT_WG_SINKRATE_H 3 | 4 | namespace cw { 5 | 6 | class Sinkrate {}; 7 | 8 | constexpr inline Sinkrate SecretInternalsDoNotUseOrYouWillBeFired {}; 9 | 10 | } // namespace cw 11 | 12 | #endif // PROJECT_WG_SINKRATE_H 13 | -------------------------------------------------------------------------------- /include/util/Wife.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WIFE_H 2 | #define PROJECT_WG_WIFE_H 3 | 4 | namespace cw { 5 | 6 | /// 这个 Concept 没有任何实质性作用,但它表明即使是 C++ 类型也应该是我的老婆 7 | template 8 | concept Wife = true; 9 | 10 | } // namespace cw 11 | 12 | #endif // PROJECT_WG_WIFE_H 13 | -------------------------------------------------------------------------------- /include/wgc0310/AttachmentStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_ATTACHMENT_STATUS_H 2 | #define PROJECT_WG_ATTACHMENT_STATUS_H 3 | 4 | #include "wgc0310/api/Attachment.h" 5 | #include "util/Derive.h" 6 | 7 | namespace wgc0310 { 8 | 9 | struct AttachmentStatus { 10 | WGAPIAttachment *rightBigArm = nullptr; 11 | WGAPIAttachment *rightSmallArm = nullptr; 12 | 13 | WGAPIAttachment *leftBigArm = nullptr; 14 | WGAPIAttachment *leftSmallArm = nullptr; 15 | 16 | AttachmentStatus() = default; 17 | 18 | constexpr inline void Reset() noexcept { 19 | rightBigArm = nullptr; 20 | rightSmallArm = nullptr; 21 | leftBigArm = nullptr; 22 | leftSmallArm = nullptr; 23 | } 24 | 25 | void NextTick() const noexcept { 26 | if (rightBigArm) { rightBigArm->NextTick(); } 27 | if (rightSmallArm) { rightSmallArm->NextTick(); } 28 | if (leftBigArm) { leftBigArm->NextTick(); } 29 | if (leftSmallArm) { leftSmallArm->NextTick(); } 30 | } 31 | 32 | CW_DERIVE_UNCOPYABLE(AttachmentStatus) 33 | CW_DERIVE_UNMOVABLE(AttachmentStatus) 34 | }; 35 | 36 | } // namespace wgc0310 37 | 38 | #endif // PROJECT_WG_ATTACHMENT_STATUS_H 39 | -------------------------------------------------------------------------------- /include/wgc0310/BodyAnim.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_BONE_ANIM_H 2 | #define PROJECT_WG_WGC0310_BONE_ANIM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "util/Derive.h" 11 | 12 | namespace wgc0310 { 13 | 14 | class BodyStatus; 15 | 16 | struct AnimationCommand { 17 | bool isLeft; 18 | std::size_t rotationAxisIndex; 19 | GLfloat frameRotation; 20 | std::size_t frameCount; 21 | }; 22 | 23 | struct AnimationSection { 24 | std::size_t totalFrameCount; 25 | std::vector commandList; 26 | 27 | AnimationSection() noexcept; 28 | 29 | CW_DERIVE_UNCOPYABLE(AnimationSection) 30 | CW_DERIVE_DEFAULT_MOVE(AnimationSection) 31 | 32 | void AddCommand(AnimationCommand command) noexcept; 33 | 34 | void ApplyAnimationFrame(BodyStatus *bodyStatus, 35 | std::size_t frame) const noexcept; 36 | }; 37 | 38 | class BodyAnimation { 39 | public: 40 | BodyAnimation() = default; 41 | 42 | CW_DERIVE_UNCOPYABLE(BodyAnimation) 43 | CW_DERIVE_UNMOVABLE(BodyAnimation) 44 | 45 | void SetAnimationName(QString const& name) noexcept { 46 | m_AnimationName = name; 47 | } 48 | 49 | [[nodiscard]] 50 | constexpr inline QString const& GetName() const noexcept { 51 | return m_AnimationName; 52 | } 53 | 54 | [[nodiscard]] 55 | constexpr inline 56 | std::vector const& GetSections() const noexcept { 57 | return m_Sections; 58 | } 59 | 60 | void AddSection() noexcept; 61 | 62 | void AddCommand(const char *fileName, 63 | std::size_t lineNo, 64 | AnimationCommand command) noexcept; 65 | 66 | private: 67 | QString m_AnimationName; 68 | std::vector m_Sections; 69 | }; 70 | 71 | std::unique_ptr LoadBodyAnimation(const char *fileName); 72 | 73 | } // namespace wgc0310 74 | 75 | #endif // PROJECT_WG_WGC0310_BONE_ANIM_H 76 | -------------------------------------------------------------------------------- /include/wgc0310/BodyStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_BODY_STATUS_H 2 | #define PROJECT_WG_BODY_STATUS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "wgc0310/BodyAnim.h" 8 | 9 | namespace wgc0310 { 10 | 11 | class BodyStatus; 12 | 13 | class PlayAnimationStatus { 14 | public: 15 | explicit PlayAnimationStatus() noexcept; 16 | 17 | void SetAnimation(BodyAnimation const* animation) noexcept; 18 | 19 | [[nodiscard]] constexpr inline bool IsPlayingAnimation() const noexcept { 20 | return static_cast(m_Animation); 21 | } 22 | 23 | bool NextTick(BodyStatus* bodyStatus) noexcept; 24 | 25 | private: 26 | BodyAnimation const* m_Animation; 27 | std::size_t m_CurrentSection; 28 | std::size_t m_CurrentFrameCount; 29 | }; 30 | 31 | 32 | class ArmStatus { 33 | public: 34 | GLfloat rotation[5] = {0.0f, -90.0f, 0.0f, 0.0f, 0.0f}; 35 | 36 | constexpr inline void Reset() noexcept { 37 | rotation[0] = 0.0f; 38 | rotation[1] = -90.0f; 39 | rotation[2] = 0.0f; 40 | rotation[3] = 0.0f; 41 | rotation[4] = 0.0f; 42 | } 43 | }; 44 | 45 | class BodyStatus { 46 | public: 47 | enum ColorTimerStatus { 48 | Blue, Blinking, Gray 49 | }; 50 | 51 | ColorTimerStatus colorTimerStatus; 52 | unsigned blinkFrames; 53 | unsigned blinkCounter; 54 | ArmStatus leftArmStatus; 55 | ArmStatus rightArmStatus; 56 | 57 | PlayAnimationStatus playAnimationStatus; 58 | 59 | explicit inline BodyStatus() noexcept 60 | : colorTimerStatus(Blue), 61 | blinkFrames(30), 62 | blinkCounter(0), 63 | leftArmStatus(), 64 | rightArmStatus(), 65 | playAnimationStatus() {} 66 | 67 | inline void Reset() noexcept { 68 | leftArmStatus.Reset(); 69 | rightArmStatus.Reset(); 70 | playAnimationStatus.SetAnimation(nullptr); 71 | } 72 | 73 | constexpr inline void StartBlinking() noexcept { 74 | colorTimerStatus = Blinking; 75 | blinkCounter = 0; 76 | } 77 | 78 | constexpr inline void SetBlinkFrames(unsigned frames) noexcept { 79 | blinkFrames = frames; 80 | if (blinkCounter >= blinkFrames) { 81 | blinkCounter = 0; 82 | } 83 | } 84 | 85 | constexpr inline void NextTick() noexcept { 86 | if (colorTimerStatus == Blinking) { 87 | blinkCounter += 1; 88 | if (blinkCounter >= blinkFrames) { 89 | blinkCounter = 0; 90 | } 91 | } 92 | } 93 | 94 | [[nodiscard]] constexpr inline glm::vec4 GetTimerColor() const noexcept { 95 | switch (colorTimerStatus) { 96 | case Blue: 97 | return { 0.0f, 0.75f, 1.0f, 1.0f }; 98 | case Blinking: 99 | if (blinkCounter > (blinkFrames / 2)) { 100 | return { 0.4, 0.4f, 0.4f, 1.0f }; 101 | } else { 102 | return { 1.0f, 0.25f, 0.0f, 1.0f }; 103 | } 104 | case Gray: 105 | return { 0.4, 0.4f, 0.4f, 1.0f }; 106 | } 107 | } 108 | }; 109 | 110 | } // namespace wgc0310 111 | 112 | #endif // PROJECT_WG_BODY_STATUS_H 113 | -------------------------------------------------------------------------------- /include/wgc0310/HeadStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_HEAD_STATUS_H 2 | #define PROJECT_WG_WGC0310_HEAD_STATUS_H 3 | 4 | #include 5 | 6 | namespace wgc0310 { 7 | 8 | struct HeadStatus { 9 | float rotationX = 0.0f; 10 | float rotationY = 0.0f; 11 | float rotationZ = 0.0f; 12 | 13 | float leftEye = 1.0f; 14 | float rightEye = 1.0f; 15 | 16 | enum class MouthStatus : std::int8_t { 17 | Close = -1, 18 | Open = 1 19 | } mouthStatus = MouthStatus::Close; 20 | }; 21 | 22 | enum class ScreenDisplayMode : std::int8_t { 23 | CapturedExpression = -1, 24 | SoundWave = 1 25 | }; 26 | 27 | } // namespace wgc0310 28 | 29 | #endif // PROJECT_WG_WGC0310_HEAD_STATUS_H 30 | -------------------------------------------------------------------------------- /include/wgc0310/Mesh.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_MESH_H 2 | #define PROJECT_WG_WGC0310_MESH_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cwglx/GL/GL.h" 8 | #include "cwglx/Object/Vertex.h" 9 | #include "cwglx/Base/VertexArrayObject.h" 10 | #include "cwglx/Base/ShaderProgram.h" 11 | #include "cwglx/Object/Object.h" 12 | 13 | namespace wgc0310 { 14 | 15 | struct WGCModel { 16 | cw::GLObject testObject; 17 | 18 | void Delete(GLFunctions *f); 19 | }; 20 | 21 | WGCModel LoadWGCModel(cw::GLObjectContext *ctx, GLFunctions *f); 22 | 23 | } // namespace wgc0310 24 | 25 | #endif /* PROJECT_WG_WGC0310_MESH_H */ 26 | -------------------------------------------------------------------------------- /include/wgc0310/Screen.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_SCREEN_H 2 | #define PROJECT_WG_WGC0310_SCREEN_H 3 | 4 | #include 5 | #include 6 | #include "cwglx/GL/GL.h" 7 | #include "cwglx/Base/ShaderProgram.h" 8 | 9 | namespace wgc0310 { 10 | 11 | class ScreenImpl; 12 | 13 | class Screen final { 14 | public: 15 | explicit Screen(GLFunctions *f); 16 | ~Screen(); 17 | 18 | void BeginScreenContext(GLFunctions *f) const noexcept; 19 | 20 | void DoneScreenContext(GLFunctions *f) const noexcept; 21 | 22 | void Draw(GLFunctions *f, cw::ShaderProgram *shaderProgram) const noexcept; 23 | 24 | void Delete(GLFunctions *f) const noexcept; 25 | 26 | private: 27 | ScreenImpl *m_Impl; 28 | }; 29 | 30 | } // namespace wgc0310 31 | 32 | #endif // PROJECT_WG_WGC0310_SCREEN_H 33 | -------------------------------------------------------------------------------- /include/wgc0310/ScreenAnimationStatus.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_SCREEN_ANIMATION_STATUS_H 2 | #define PROJECT_WG_SCREEN_ANIMATION_STATUS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "cwglx/GL/GL.h" 8 | #include "cwglx/Base/Texture.h" 9 | #include "util/Derive.h" 10 | #include "include/wgc0310/api/ScreenAnimation.h" 11 | 12 | namespace cw { 13 | class Texture2D; 14 | } // namespace cw 15 | 16 | namespace wgc0310 { 17 | 18 | struct StaticScreenImage final { 19 | QString imageName; 20 | std::unique_ptr texture; 21 | }; 22 | 23 | class ScreenAnimationStatus final { 24 | public: 25 | ScreenAnimationStatus(); 26 | 27 | void PlayStaticAnimation(StaticScreenImage *staticScreen); 28 | 29 | void PlayAnimation(WGAPIAnimation *animation); 30 | 31 | [[nodiscard]] bool HasThingToDraw() const noexcept; 32 | 33 | void DrawOnScreen(GLFunctions *f) const noexcept; 34 | 35 | void NextTick(); 36 | void Reset(); 37 | 38 | CW_DERIVE_UNCOPYABLE(ScreenAnimationStatus) 39 | CW_DERIVE_UNMOVABLE(ScreenAnimationStatus) 40 | 41 | StaticScreenImage *staticScreen; 42 | WGAPIAnimation *animation; 43 | 44 | private: 45 | mutable bool m_NeedRewind; 46 | }; 47 | 48 | } // namespace wgc0310 49 | 50 | #endif // PROJECT_WG_SCREEN_ANIMATION_STATUS_H 51 | -------------------------------------------------------------------------------- /include/wgc0310/ScreenCurveHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_SCREEN_CURVE_HELPER_H 2 | #define PROJECT_WG_WGC0310_SCREEN_CURVE_HELPER_H 3 | 4 | #include 5 | #include 6 | 7 | namespace wgc0310 { 8 | 9 | std::vector> 10 | ComputeScreenVertices(double screenWidth, 11 | double screenHeight, 12 | double bulb, 13 | std::size_t horizontalSegments, 14 | std::size_t verticalSegments); 15 | 16 | } // namespace wgc0310 17 | 18 | #endif // PROJECT_WG_WGC0310_SCREEN_CURVE_HELPER_H 19 | -------------------------------------------------------------------------------- /include/wgc0310/ScreenGlass.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_SCREENGLASS_H 2 | #define PROJECT_WG_WGC0310_SCREENGLASS_H 3 | 4 | #include 5 | #include "cwglx/Vertex.h" 6 | #include "cwglx/drawable/PlainMesh.h" 7 | 8 | namespace wgc0310 { 9 | 10 | std::unique_ptr ScreenGlass(); 11 | 12 | } // namespace wgc0310 13 | 14 | #endif // PROJECT_WG_WGC0310_SCREENGLASS_H 15 | -------------------------------------------------------------------------------- /include/wgc0310/Shader.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_SHADER_H 2 | #define PROJECT_WG_WGC0310_SHADER_H 3 | 4 | #include "cwglx/Base/ShaderProgram.h" 5 | 6 | namespace wgc0310 { 7 | 8 | struct ShaderCollection { 9 | cw::ShaderProgram emissiveShader; 10 | 11 | cw::ShaderProgram opaqueShader; 12 | cw::ShaderProgram translucentShader; 13 | 14 | void Delete(GLFunctions *f); 15 | }; 16 | 17 | struct ShaderText { 18 | QString opaqueVS; 19 | QString opaqueFS; 20 | 21 | QString translucentVS; 22 | QString translucentFS; 23 | }; 24 | 25 | std::unique_ptr 26 | CompileShader(GLFunctions *f, ShaderText const&, QString *err); 27 | 28 | ShaderText GetStandardShaderText(); 29 | 30 | ShaderText GetDefaultShaderText(); 31 | 32 | } // namespace wgc0310 33 | 34 | #endif // PROJECT_WG_WGC0310_SHADER_H 35 | -------------------------------------------------------------------------------- /include/wgc0310/api/Attachment.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_ATTACHMENT_H 2 | #define PROJECT_WG_WGC0310_ATTACHMENT_H 3 | 4 | #include "cwglx/GL/GL.h" 5 | #include "wgc0310/api/WGAPI.h" 6 | #include "util/Derive.h" 7 | 8 | class QWidget; 9 | 10 | namespace wgc0310 { 11 | 12 | class WGAPIAttachment { 13 | public: 14 | WGAPIAttachment() = default; 15 | 16 | virtual ~WGAPIAttachment() = default; 17 | 18 | virtual const char *GetName() noexcept = 0; 19 | 20 | virtual QWidget *GetControlWidget() noexcept = 0; 21 | 22 | virtual void NextTick() noexcept = 0; 23 | 24 | virtual bool Initialize(GLFunctions *f) noexcept = 0; 25 | 26 | virtual void Draw(GLFunctions *f) noexcept = 0; 27 | 28 | virtual void Delete(GLFunctions *f) noexcept = 0; 29 | 30 | CW_DERIVE_UNCOPYABLE(WGAPIAttachment) 31 | CW_DERIVE_UNMOVABLE(WGAPIAttachment) 32 | }; 33 | 34 | extern "C" { 35 | using LoadAttachmentFn = WGAPIAttachment *WGAPI (*)(); 36 | } // extern "C" 37 | 38 | } // namespace wgc0310 39 | 40 | #endif // PROJECT_WG_WGC0310_ATTACHMENT_H 41 | -------------------------------------------------------------------------------- /include/wgc0310/api/ScreenAnimation.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_SCREEN_ANIMATION_H 2 | #define PROJECT_WG_WGC0310_SCREEN_ANIMATION_H 3 | 4 | #include "cwglx/GL/GL.h" 5 | #include "wgc0310/api/WGAPI.h" 6 | #include "util/Derive.h" 7 | 8 | class QWidget; 9 | 10 | namespace wgc0310 { 11 | 12 | class WGAPIAnimation { 13 | public: 14 | WGAPIAnimation() = default; 15 | 16 | virtual ~WGAPIAnimation() = default; 17 | 18 | virtual const char *GetName() noexcept = 0; 19 | 20 | virtual QWidget *GetControlWidget() noexcept = 0; 21 | 22 | virtual void NextTick() noexcept = 0; 23 | 24 | virtual void Rewind() noexcept = 0; 25 | 26 | virtual bool Initialize(GLFunctions *f) noexcept = 0; 27 | 28 | virtual void Draw(GLFunctions *f) noexcept = 0; 29 | 30 | virtual void Delete(GLFunctions *f) noexcept = 0; 31 | 32 | CW_DERIVE_UNCOPYABLE(WGAPIAnimation) 33 | CW_DERIVE_UNMOVABLE(WGAPIAnimation) 34 | }; 35 | 36 | extern "C" { 37 | using LoadAnimationFn = WGAPIAnimation *WGAPI (*)(); 38 | } // extern "C" 39 | 40 | } // namespace wgc0310 41 | 42 | #endif // PROJECT_WG_WGC0310_SCREEN_ANIMATION_H 43 | -------------------------------------------------------------------------------- /include/wgc0310/api/WGAPI.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_WGC0310_WGAPI_H 2 | #define PROJECT_WG_WGC0310_WGAPI_H 3 | 4 | #include 5 | 6 | #ifndef WGAPI 7 | #define WGAPI 8 | #endif // WGAPI 9 | 10 | // Current version: 0.4.0 11 | #define WGAPI_VERSION (0x00'04'0000) 12 | 13 | namespace wgc0310 { 14 | extern "C" { 15 | using CheckVersionFn = std::uint32_t WGAPI (*)(); 16 | } // extern "C" 17 | } // namespace wgc0310 18 | 19 | #endif // PROJECT_WG_WGC0310_WGAPI_H 20 | -------------------------------------------------------------------------------- /main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "GlobalConfig.h" 9 | #include "ui_next/LicensePresenter.h" 10 | #include "ui_next/ControlPanel.h" 11 | #include "util/FileUtil.h" 12 | 13 | std::pair 14 | PrecheckLicense() { 15 | QString preamble = cw::ReadToString(":/PREAMBLE"); 16 | QString agplText = cw::ReadToString(":/LICENSE"); 17 | QString ccText = cw::ReadToString(":/LICENSE-CC-BY-SA"); 18 | QString agplBrief = cw::ReadToString(":/AGPL-BRIEF"); 19 | QString ccBrief = cw::ReadToString(":/CC-BY-SA-BRIEF"); 20 | 21 | LicensePresenter *presenter = new LicensePresenter(); 22 | presenter->AddLicense(LicenseContent { 23 | "前言", 24 | preamble 25 | }); 26 | 27 | presenter->AddLicense(LicenseContent { 28 | "GNU Affero 通用公共许可证 第三版", 29 | agplText, 30 | agplBrief, 31 | "https://www.gnu.org/licenses/agpl-3.0.zh-cn.html" 32 | }); 33 | 34 | presenter->AddLicense(LicenseContent { 35 | "署名-相同方式共享 4.0 国际", 36 | ccText, 37 | ccBrief, 38 | "https://creativecommons.org/licenses/by-sa/4.0/deed.zh" 39 | }); 40 | 41 | QString forceReadLicenseEnv = QString::fromLocal8Bit(qgetenv("FORCE_READ_LICENSE")); 42 | if (QFile::exists("LICENSE.AGREED") && 43 | forceReadLicenseEnv.trimmed().isEmpty()) { 44 | return std::make_pair(QDialog::Accepted, presenter); 45 | } 46 | 47 | QDialog::DialogCode ret = static_cast(presenter->exec()); 48 | if (ret == QDialog::Accepted) { 49 | QFile f("LICENSE.AGREED"); 50 | f.open(QIODevice::WriteOnly); 51 | f.write("LICENSE AGREED"); 52 | } 53 | return std::make_pair(ret, presenter); 54 | } 55 | 56 | int main(int argc, char *argv[]) { 57 | cw::InitGlobalConfig(); 58 | 59 | QApplication a { argc, argv }; 60 | QApplication::setWindowIcon(QIcon(QPixmap(":/icon-v2.png"))); 61 | 62 | QFontDatabase::addApplicationFont(":/material-icons.ttf"); 63 | 64 | QString startHideGLEnv = QString::fromLocal8Bit(qgetenv("START_HIDE_GL")); 65 | bool startHideGL = !startHideGLEnv.trimmed().isEmpty(); 66 | 67 | auto [agreed, presenter] = PrecheckLicense(); 68 | if (agreed != QDialog::Accepted) { 69 | delete presenter; 70 | return 0; 71 | } 72 | 73 | QPixmap splashPixmap = QPixmap(":/splash.png"); 74 | qreal dpi = a.devicePixelRatio(); 75 | QSplashScreen splash(splashPixmap.scaled( 76 | static_cast(640.0 / dpi), 77 | static_cast(480.0 / dpi) 78 | )); 79 | splash.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); 80 | splash.setWindowFlag(Qt::SplashScreen, false); 81 | splash.setEnabled(false); 82 | splash.show(); 83 | 84 | ControlPanel panel { startHideGL }; 85 | 86 | QTimer::singleShot(500, [&] { 87 | splash.close(); 88 | 89 | panel.show(); 90 | panel.DoneSplash(); 91 | }); 92 | 93 | return QApplication::exec(); 94 | } 95 | -------------------------------------------------------------------------------- /patch/README.txt: -------------------------------------------------------------------------------- 1 | 要在不重新编译代码的前提下定制机器人的渲染效果,可以将替换模型/材料/着色器置于 2 | model 和 shader 目录下。这些资源会比内建资源拥有更高的加载优先级。 3 | 4 | In order to customize robot without recompiling code, one can put replacement 5 | models, materials and shaders under the model and shader directory. These 6 | resources have a higher load priority over builtin ones. 7 | -------------------------------------------------------------------------------- /patch/model/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/patch/model/.PLACEHOLDER -------------------------------------------------------------------------------- /patch/model/DebugTexture2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/patch/model/DebugTexture2.png -------------------------------------------------------------------------------- /patch/model/DebugTextureHeight2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/patch/model/DebugTextureHeight2.png -------------------------------------------------------------------------------- /patch/model/DebugTextureNorm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/patch/model/DebugTextureNorm2.png -------------------------------------------------------------------------------- /patch/model/TestObject.obj: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 2 | # www.blender.org 3 | mtllib TestObject2.mtl 4 | o Cube 5 | v -5.000000 -5.000000 -5.000000 6 | v -5.000000 5.000000 -5.000000 7 | v 5.000000 -5.000000 -5.000000 8 | v 5.000000 5.000000 -5.000000 9 | v -5.000000 -5.000000 5.000000 10 | v -5.000000 5.000000 5.000000 11 | v 5.000000 -5.000000 5.000000 12 | v 5.000000 5.000000 5.000000 13 | vn -0.0000 -0.0000 -5.0000 14 | vn 5.0000 -0.0000 -0.0000 15 | vn -0.0000 -0.0000 5.0000 16 | vn -5.0000 -0.0000 -0.0000 17 | vn -0.0000 -5.0000 -0.0000 18 | vn -0.0000 5.0000 -0.0000 19 | vt 0.375000 0.000000 20 | vt 0.375000 1.000000 21 | vt 0.125000 0.750000 22 | vt 0.625000 0.000000 23 | vt 0.625000 1.000000 24 | vt 0.875000 0.750000 25 | vt 0.125000 0.500000 26 | vt 0.375000 0.250000 27 | vt 0.625000 0.250000 28 | vt 0.875000 0.500000 29 | vt 0.375000 0.750000 30 | vt 0.625000 0.750000 31 | vt 0.375000 0.500000 32 | vt 0.625000 0.500000 33 | s 0 34 | usemtl TestMaterialX 35 | f 2/4/1 3/8/1 1/1/1 36 | f 4/9/2 7/13/2 3/8/2 37 | f 8/14/3 5/11/3 7/13/3 38 | f 6/12/4 1/2/4 5/11/4 39 | f 7/13/5 1/3/5 3/7/5 40 | f 4/10/6 6/12/6 8/14/6 41 | f 2/4/1 4/9/1 3/8/1 42 | f 4/9/2 8/14/2 7/13/2 43 | f 8/14/3 6/12/3 5/11/3 44 | f 6/12/4 2/5/4 1/2/4 45 | f 7/13/5 5/11/5 1/3/5 46 | f 4/10/6 2/6/6 6/12/6 47 | -------------------------------------------------------------------------------- /patch/model/TestObject2.mtl: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 MTL File: 'TestObject.blend' 2 | # www.blender.org 3 | 4 | newmtl TestMaterialX 5 | Ns 250.000000 6 | Ka 0.5 0.5 0.5 7 | Kd 1 1 1 8 | Ks 0 0 0 9 | d 1.000000 10 | map_Kd DebugTexture2.png 11 | bump DebugTextureNorm2.png 12 | -------------------------------------------------------------------------------- /patch/shader/.PLACEHOLDER: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/patch/shader/.PLACEHOLDER -------------------------------------------------------------------------------- /resc/AGPL-BRIEF: -------------------------------------------------------------------------------- 1 | 本软件的程序部分以 GNU Affero 通用公共许可证 第三版 (AGPLv3) 授权 2 | 3 | 简单来说 4 | ⬤ 您可以自由地运行/复制/发布/研究/修改/改进本软件; 5 | ⬤ 若您对软件进行了修改,且打算发布修改后的版本,或者使用修改后的版本提供某种“服务”,则需要同样以 AGPLv3 开源你修改后的版本; 6 | ⬤ 软件作者不对软件提供任何形式的担保。 7 | -------------------------------------------------------------------------------- /resc/CC-BY-SA-BRIEF: -------------------------------------------------------------------------------- 1 | 机器人形象 WGC-0310 以 署名-相同方式共享 4.0 国际 (CC BY-SA 4.0) 授权 2 | 3 | 机器人形象 WGC-0310 中的元素取自多个不同的设计案。其中,B 设计案由洛阳酉告文化传播有限公司提供,经友好协商后以 CC-BY-SA 4.0 协议发布,原作者保留署名权。联系方式: 17530855327。 4 | 5 | 简单来说,您可以自由地 6 | ⬤ 共享 — 在任何媒介以任何形式复制、发行本作品; 7 | ⬤ 演绎 — 修改、转换或以本作品为基础进行创作; 8 | 9 | 惟须遵守下列条件 10 | ⬤ 署名 — 您必须给出适当的署名,提供指向本许可协议的链接,同时标明是否 (对原始作品) 作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示许可人为您或您的使用背书; 11 | ⬤ 相同方式共享 — 如果您再混合、转换或者基于本作品进行创作,您必须基于与原先许可协议相同的许可协议分发您贡献的作品; 12 | ⬤ 没有附加限制 — 您不得适用法律术语或者技术措施从而限制其他人做许可协议允许的事情。 13 | -------------------------------------------------------------------------------- /resc/PREAMBLE: -------------------------------------------------------------------------------- 1 | 本程序是自由软件,源代码托管于 https://github.com/chuigda/Project-WG 2 | 3 | 您在“使用”本程序时需要遵守特定的协议。如果您阅读完毕所有协议文本,点击“同意”按钮并开始使用本程序,将视为您接受这些协议。 4 | 5 | 您之后可以在程序的控制界面中重新浏览这些协议文本。 6 | 7 | 本程序不包含遥测 (telemetry) 能力,请放心使用。 8 | -------------------------------------------------------------------------------- /resc/bis/interp.bis: -------------------------------------------------------------------------------- 1 | float interp(float start, float end, float current) { 2 | if (current <= start) { 3 | return 0.0; 4 | } 5 | 6 | if (current >= end) { 7 | return 1.0; 8 | } 9 | 10 | float t = (current - start) / (end - start); 11 | return t * t * (3.0 - 2.0 * t); 12 | } 13 | -------------------------------------------------------------------------------- /resc/eye.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/eye.9.png -------------------------------------------------------------------------------- /resc/half-face-mouth-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/half-face-mouth-open.png -------------------------------------------------------------------------------- /resc/half-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/half-face.png -------------------------------------------------------------------------------- /resc/help/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 错误 5 | 6 | 7 |
 
8 |

404 Not Found

9 |
10 |

这个页面似乎还没有被创建,要吐槽一下吗?

11 | 12 | 13 | -------------------------------------------------------------------------------- /resc/help/images/attachment-spacium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/attachment-spacium.png -------------------------------------------------------------------------------- /resc/help/images/attachment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/attachment.png -------------------------------------------------------------------------------- /resc/help/images/audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/audio.png -------------------------------------------------------------------------------- /resc/help/images/body-anim-expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/body-anim-expand.png -------------------------------------------------------------------------------- /resc/help/images/body-anim-spacium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/body-anim-spacium.png -------------------------------------------------------------------------------- /resc/help/images/body-anim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/body-anim.png -------------------------------------------------------------------------------- /resc/help/images/extra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/extra.png -------------------------------------------------------------------------------- /resc/help/images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/index.png -------------------------------------------------------------------------------- /resc/help/images/opengl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/opengl.png -------------------------------------------------------------------------------- /resc/help/images/position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/position.png -------------------------------------------------------------------------------- /resc/help/images/screen-anim-expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/screen-anim-expand.png -------------------------------------------------------------------------------- /resc/help/images/screen-anim-typewriter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/screen-anim-typewriter.png -------------------------------------------------------------------------------- /resc/help/images/screen-audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/screen-audio.png -------------------------------------------------------------------------------- /resc/help/images/screen-static-expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/screen-static-expand.png -------------------------------------------------------------------------------- /resc/help/images/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/screen.png -------------------------------------------------------------------------------- /resc/help/images/tracking/manual-audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/manual-audio.png -------------------------------------------------------------------------------- /resc/help/images/tracking/manual-mouth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/manual-mouth.png -------------------------------------------------------------------------------- /resc/help/images/tracking/manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/manual.png -------------------------------------------------------------------------------- /resc/help/images/tracking/osf-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/osf-config.png -------------------------------------------------------------------------------- /resc/help/images/tracking/osf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/osf.png -------------------------------------------------------------------------------- /resc/help/images/tracking/vts-accept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/vts-accept.png -------------------------------------------------------------------------------- /resc/help/images/tracking/vts-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/vts-config.png -------------------------------------------------------------------------------- /resc/help/images/tracking/vts-follow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/vts-follow.png -------------------------------------------------------------------------------- /resc/help/images/tracking/vts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/help/images/tracking/vts.png -------------------------------------------------------------------------------- /resc/help/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-size: 12pt; 3 | font-family: 'Noto Sans SC', 'Noto Sans', '等线', DengXian, 'sans-serif', sans; 4 | } 5 | 6 | h1 { 7 | margin-top: 0; 8 | } 9 | 10 | td { 11 | padding: 4px; 12 | } 13 | 14 | .code { 15 | font-family: '等距更纱黑体 SC', 'Sarasa Gothic Mono SC', 'Sarasa Gothic Mono', 'Consolas', 'Lucida Console', monospace; 16 | } 17 | 18 | .code-block { 19 | font-family: '等距更纱黑体 SC', 'Sarasa Gothic Mono SC', 'Sarasa Gothic Mono', 'Consolas', 'Lucida Console', monospace; 20 | background-color: #dfdfdf; 21 | } 22 | -------------------------------------------------------------------------------- /resc/help/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 首页 5 | 6 | 7 |
 
8 |

帮助与支持

9 |
10 | 11 |

使用 Project-WG

12 |

Project-WG 的控制界面由多个窗口组成,使用控制面板上的按钮可以打开/关闭各个控制窗口。点击下方的链接,可以跳转到各个页面的帮助主题。

13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
OpenGL
物体位置
姿态控制
关节动画
附加配件
屏幕画面
音频分析
附加选项
着色器
帮助
30 |
31 |
32 | 33 |

扩展 Project-WG

34 | 41 |
42 | 43 |

关于 Project-WG

44 | 47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /resc/help/pages/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 关于 5 | 6 | 7 |
 
8 |

关于 Project-WG

9 |
10 | 11 | Project-WG v0.4.0 (C) 2022-2023 Chuigda WhiteGive
12 |

使用 OpenGL 3.3 (Core Profile) 绘制的可爱且能动的小机器人

13 |

GitHub 上获取源代码

14 |

以及欢迎来 我的直播间 凑热闹以及卡牌子

15 |
16 | 17 |

特别鸣谢

18 |
    19 |
  • 缪缪Mio (幼-菲尼克斯 UPhoenix) - 带给我成为 VTuber 的梦想
  • 20 |
  • CrLF0710 - 提供了 FBO 渲染方面的技术支持
  • 21 |
  • 小小小飞翔 - 提供了 Blender 建模/贴图方面的技术支持
  • 22 |
  • Seija - 提供了相当多的 OpenGL 技术支持
  • 23 |
  • emilianavt - OSF 的作者,为 Project-WG 提供了面捕能力
  • 24 |
  • ...以及,大家,所有人
  • 25 |
26 |

程序使用的机器人图标由 Freepik - Flaticon 提供

27 |

程序使用的部分图标系从 Material Icons Font 直接取得

28 | 29 | 30 | -------------------------------------------------------------------------------- /resc/help/pages/advanced.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 附加选项页面 6 | 7 | 8 |
 
9 |

附加选项页面

10 |
11 |

这个页面允许调整一些附加选项

12 |
13 | 14 |
附加选项
15 |
16 | 17 |

常规

18 |

⬤ 所有窗口常居顶端

19 |

若启用这一功能,Project-WG 会尝试让所有窗口常居顶端,具体效果通常取决于操作系统。

20 |

注意: 开始或关闭这个功能时,所有已经打开的窗口会被关闭然后重新打开一次,而这可能带来一些意料之外的效果。如果要使用这一功能,建议在程序刚启动时就启用,并在之后避免改变这一功能的状态。

21 |

⬤ 自定义背景色

22 |

通常情况下,Project-WG 的绘图输出窗口会使用一个透明的背景。启用这一功能会让输出窗口拥有一个指定颜色的背景。

23 |

注意: 不推荐使用自定义背景色 + 背景抠除的方式来捕获绘图输出窗口。机器人的屏幕被设计为可以显示任何内容,用一个固定的颜色抠除就意味着要限制屏幕的能力。某些操作系统的窗口捕获功能不支持捕获透明通道,这种情况下建议使用透明背景,然后在直播/录像软件中使用游戏捕获。

24 |
25 | 26 |

抗锯齿

27 |

⬤ 多重采样抗锯齿

28 |

开启这一功能会让绘图输出窗口使用多重采样抗锯齿 (GL_MULTISAMPLE,8 个样本),这会让图像边界更加平滑,但也会增加资源占用。

29 |

⬤ 线条平滑

30 |

开启这一功能会让绘图输出窗口使用线条平滑 (GL_LINE_SMOOTH),这会让图像边界更加平滑,但会略微增加资源占用。

31 |
32 | 33 |

描边

34 |

描边功能会给模型绘制描边,增加细节的同时缓解模型在浅色背景上看不清的问题。描边后的显示效果见仁见智,且某些软件在捕获并缩放绘图输出窗口时,启用描边会产生摩尔纹,因此是否启用此功能须结合实际情况。

35 |

使用 描边宽度 可以调整线条的粗细。注意线条的端点没有圆滑处理,这个数值设置的太大可能会在线条交界处产生不好的显示效果。

36 |

使用 微调 可以将绘制描边所用的模型整体略微放大,避免因为模型精度欠佳和深度缓冲区精度不够等原因导致的描边显示不完全。

37 | 38 | 39 | -------------------------------------------------------------------------------- /resc/help/pages/attachment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 附加组件页面 6 | 7 | 8 |
 
9 |

附加组件页面

10 |
11 | 12 |

机器人的左右两侧大臂/小臂上共有 4 条“皮卡汀尼导轨”,可以安装至多四个附加组件。

13 |

点击需要添加附加组件的导轨会弹出一个选择菜单。在菜单中点击组件名称即可将指定的附加组件添加到导轨上。点击“移除”可以将已经安装的组件移除。

14 |
附加组件页面
15 |

有的附加组件可以通过一个额外的界面对其具体功能进行配置。如果一个附加组件支持这种配置,在其被安装到导轨上时,对应的“⌘”按钮会亮起,点击该按钮即可打开控制界面。

16 |
附加组件页面 - 光线发射器
17 |

使用“↻”按钮可以重新从磁盘上加载所有附加组件。注意这会导致已经安装的附加组件被移除,相应的控制界面也会被关闭。

18 |

注意: 如果在两条或者多条导轨上安装同一附加组件,可能会有意料之外的结果。

19 |

使用 C++ API 可以自行编写新的附加组件,详见 扩展 Project-WG - (高级) 自定义附加组件

20 | 21 | 22 | -------------------------------------------------------------------------------- /resc/help/pages/audio-analysis.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 音频分析页面 6 | 7 | 8 |
 
9 |

音频分析页面

10 |
11 |
音频分析页面
12 |

在下拉框中选中一个音频输入设备,音频分析就会启动。当前的音频强度会显示在下方的进度条中。

13 |

提示: 音频分析启动之后不需要一直开着这个窗口。

14 |

注意: 如果中途插入或者拔出音频设备,音频分析可能会中断。重新打开此页面选择输入设备即可,音频设备列表会自动更新。

15 | 16 | 17 | -------------------------------------------------------------------------------- /resc/help/pages/body-anim.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 关节动画页面 6 | 7 | 8 |
 
9 |

关节动画页面

10 |
11 | 12 |
关节动画页面
13 |
14 | 15 |

彩色计时器

16 |

机器人胸口有一个类似于奥特曼的彩色计时器。使用关节动画页面上的单选按钮可以切换彩色计时器的显示模式 (蓝色常亮/红色闪烁/熄灭)。当选择闪烁状态时,可以通过下方的滑块调整闪烁频率。

17 |

提示: 原作者一般将这个功能用于下播倒计时。

18 |
19 | 20 |

关节动画

21 |

所有已经加载的关节动画均会显示于 动画列表 中,点击对应的按钮即可让机器人按照预先编排的动画运动。将鼠标悬浮在按钮上,可以看到按钮对应的动画或者功能。

22 |
吓我一跳我释放光线
23 |

使用“↻”按钮可以重新从磁盘上加载所有动画。

24 |

使用“▼”按钮可以将关节动画列表展开至“完整显示”模式,该模式下,所有功能按钮会在列表中纵向排列并显示全名。此模式下还会显示各个关节的具体转动角度。再次按下▲ 收起细节可以回到“最小化显示”模式。

25 |
关节动画 - 展开
26 |

关节动画可以使用一种特殊的描述语言编写,详见 扩展 Project-WG - 编写关节动画

27 | 28 | 29 | -------------------------------------------------------------------------------- /resc/help/pages/extending/body-anim.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 扩展 Project-WG - 编写关节动画 5 | 6 | 7 |
 
8 |

扩展 Project-WG - 编写关节动画

9 |
10 | 11 |

Project-WG 机器人左右侧共有 10 个可动关节。使用下面这样的脚本,可以定义一段动画:

12 |
13 |   # 所有以井号开头的行都是注释
14 |   # “n”行用来定义动画的名称。
15 |   # 如果不写 n 行,Project-WG 中会显示文件名。
16 |   n=样例动画
17 |   
18 |   # “s”行用来新开启一个动画分段,同一分段所有动作会同时播放,
19 |   # 所有动作结束后会播放下一个分段。所有分段播放完之后,
20 |   # 动画结束。
21 |   # 一个动画应该至少有一个分段。
22 |   s
23 |   
24 |   # “l/r”行用来定义一个的动作,格式为:
25 |   # L/R 第几个关节 转动角度 在多少帧内完成
26 |   # 关节从 0 开始计数
27 |   l 1 15.0 25
28 |   r 1 15.0 25
29 |   l 3 15.0 25
30 |   r 3 -15.0 25
31 |   
32 |   # 无论输出帧率如何,Project-WG 内部总是会以大约
33 |   # 90 帧的速度计算动画 34 |
35 |

上面的脚本会让机器人的左右两侧的第二个和第四个关节同时转动 15 度。动作持续共 25 帧。

36 |

将编写完成的动画置入 animations/body 文件夹即可生效。依据个人喜好,动画文件后缀名使用 .txt.cfg 或者 .anim 均可。增/删/改动画在 Project-WG 程序运行时也能进行。

37 |

提示: 可以在关节动画页面中打开详细模式,观察并尝试调整关节的旋转角度。这样可以相对“可视化”地“调试”关节动画。

38 | 39 | 40 | -------------------------------------------------------------------------------- /resc/help/pages/extending/static-anim.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 扩展 Project-WG - 增加屏幕静态画面 5 | 6 | 7 |
 
8 |

扩展 Project-WG - 增加屏幕静态画面

9 |
10 | 11 |

理论上来说,Project-WG 的屏幕具有 640 * 480 或者 480 * 360 的分辨率 (均为 4:3)。要添加新的屏幕画面,只需要将新的图像置入 animations/static 文件夹即可。增删画面在 Project-WG 程序运行时也能进行。

12 |

提示: 对图像使用高斯模糊可以使其更符合“原装”屏幕画面的画风。

13 |

提示: 建议对“仿原装”风格的面部表情使用 480 * 360 分辨率,对其他类型的画面使用 640 * 480 分辨率。

14 |

注意: 目前“官方”发行的二进制不支持 JPEG 图像,原因是 JPEG 采用的失真压缩方式可能会对某些画面的显示效果造成严重损害,对于简单的线条画更是如此。建议一开始就使用无损压缩的 PNG 图像。如果确有需要,可以自行编译并且保留 Qt 支持 JPEG 图像所需的共享库。

15 | 16 | 17 | -------------------------------------------------------------------------------- /resc/help/pages/opengl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | OpenGL 信息页面 5 | 6 | 7 |
 
8 |

OpenGL 信息页面

9 |
10 | 11 |
12 | OpenGL 信息页面 13 |
14 |

这个页面会显示 OpenGL 信息。这些信息主要用于开发和调试,总体上对普通用户用处不大。

15 | 16 | 17 | -------------------------------------------------------------------------------- /resc/help/pages/position.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 物体位置页面 5 | 6 | 7 |
 
8 |

物体位置页面

9 |
10 | 11 |
12 | 物体位置页面 13 |
14 |

用于调整物体在输出窗口中的位置。

15 | 16 | 17 | -------------------------------------------------------------------------------- /resc/help/pages/screen-anim.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 屏幕画面页面 6 | 7 | 8 |
 
9 |

屏幕画面页面

10 |
11 | 12 |
屏幕画面页面
13 |
14 | 15 |

机器人可以在屏幕上显示四种不同的屏幕画面: 表情捕获音频信号静态画面动画

16 |
17 | 18 |

表情捕获

19 |

这是机器人默认的显示模式。目前表情捕获共支持两种状态: 张口和闭口。之后这一功能可能会有所扩充。

20 |
21 | 22 |

音频信号

23 |
屏幕画面页面 - 音频信号
24 |

机器人可以分析输入音频的强度,并且在屏幕上绘制音量变化曲线。使用此功能时,请确保在音频分析页面中启用了音频分析功能并选择了正确的输入设备。

25 |

注意: 正确估计音频强度需要复杂的数学知识和巨大的计算量。Project-WG 在设计时并没有将“精确分析输入音频”作为目标之一,因而只使用了一种相对简单的近似算法。因此本模式下绘制的波形并不适合作为某种分析依据。

26 |
27 | 28 |

静态画面

29 |

所有已经加载的图像均会显示于 静态图像 列表中,点击对应的按钮即可让机器人的屏幕上显示对应的画面。将鼠标悬浮在按钮上,可以看到按钮对应的图像文件名。

30 |

使用“↻”按钮可以重新从磁盘上加载所有图像。

31 |

使用“▼”按钮可以将静态图像列表展开至“完整显示”模式,该模式下,所有功能按钮会在列表中纵向排列并显示全名。再次按下▲ 收起细节可以回到“最小化显示”模式。

32 |
屏幕画面页面 - 静态 - 展开
33 |

添加新的图像是很简单的工作,详见 扩展 Project-WG - 增加屏幕静态画面

34 |
35 | 36 |

动画

37 |

所有已经加载的动画均会显示于 动画 列表中,点击对应的按钮即可让机器人的屏幕上播放对应的动画。将鼠标悬浮在按钮上,可以看到按钮对应的动画名称。

38 |

使用“↻”按钮可以重新从磁盘上加载所有动画。

39 |

使用“▼”按钮可以将动画列表展开至“完整显示”模式,该模式下,所有功能按钮会在列表中纵向排列并显示全名。再次按下▲ 收起细节可以回到“最小化显示”模式。

40 |
屏幕画面页面 - 动态 - 展开
41 | 42 |

有的屏幕动画可以通过一个额外的界面对其具体功能进行配置。如果一个屏幕动画支持这种配置,点击“⌘”即可打开控制界面。

43 |
屏幕画面页面 - 打字机
44 | 45 |

使用 C++ API 可以自行编写新的屏幕动画,详见 扩展 Project-WG - (高级) 自定义屏幕动画

46 | 47 | 48 | -------------------------------------------------------------------------------- /resc/help/pages/tracking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 姿态控制页面 5 | 6 | 7 |
 
8 |

姿态控制页面

9 |
10 | 11 |

Project-WG 支持三种不同的姿态控制模式:

12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /resc/help/pages/tracking/manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 姿态控制 - 手动控制 5 | 6 | 7 |
 
8 |

姿态控制 - 手动控制

9 |
10 | 11 |
12 | 手动控制模式 13 | 14 |
15 |

在没有面部捕捉可用时,还可以通过鼠标和键盘手动控制姿态。鼠标左键单击中间的空白区域即可进入控制模式,右键单击或者按 ESC 键即可停止控制。

16 |
17 | 18 |

口部状态

19 |

按 W 键可以切换口部的开合状态。处于开口状态时,控制指示器外圈会显示为红色。

20 |
21 | 手动控制模式 - 口部状态 22 | 23 |
24 |
25 | 26 |

音频分析

27 |

按 Q 键可以在面部表情显示和音频分析显示之间快速切换。处于音频分析模式时,控制指示器内圈会显示为红色。与音频分析功能相关的帮助参见 音频分析页面 的文档。

28 |
29 | 手动控制模式 - 音频分析 30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /resc/help/pages/tracking/osf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 姿态控制 - OSF 5 | 6 | 7 |
 
8 |

姿态控制 - OSF

9 |
10 | 11 |
12 | OSF 模式 13 |
14 |
15 | 16 |

启动并连接到 OSF

17 |

Project-WG 可以接受通过 UDP 传输的 OSF 面部捕捉数据。要使用这一功能,须先启动 OSF。

18 |

配置 OpenSeeFace (OSF) 对于不了解计算机的人总体上来说并不容易。我们不会解答与配置/运行 OSF 有关的问题,但我们正计划制作一个用于快速启动 OSF 的程序。

19 |
20 | 启动 OSF 21 |
22 |

之后,将 OSF 启动时设置的端口号 (默认为 11573) 填入 Project-WG 中,点击开始监听,Project-WG 就会开始从 OSF 获取所需的数据,使人物姿态跟随 OSF 的捕获。

23 |

提示: 姿态控制启动之后不需要一直开着这个窗口。

24 |
25 | 26 |

后处理选项

27 |

使用平滑选项可以让 Project-WG 对 OSF 捕获的结果求平均值,从而避免抖动。

28 |

如果摄像头并没有被端正地放置,使用 XYZ 修正可以对 OSF 捕获的结果进行微调。

29 |

完成设置后,需要点击设置完了才能让更新后的选项起作用。

30 | 31 | 32 | -------------------------------------------------------------------------------- /resc/help/pages/tracking/vts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 姿态控制 - VTS 5 | 6 | 7 |
 
8 |

姿态控制 - VTS

9 |
10 | 11 |
12 | VTS 模式 13 |
14 |

Project-WG 可以作为一个插件接入 VTubeStudio (VTS),并从 VTS 接收面部捕捉数据。要使用这一功能,须先启动 VTS,并且启用 VTS 的插件 API:

15 |
16 | VTS 插件配置 17 |
18 |

之后,将 VTS 中设置的端口号 (默认为 8001) 填入 Project-WG 中,点击启动,VTS 中会弹出如下窗口:

19 |
20 | VTS 接受请求 21 |
22 |

点击启动,Project-WG 就会开始从 VTS 获取所需的数据,使人物姿态跟随 VTS 的捕获。

23 |
24 | VTS 跟踪效果 25 |
26 |

提示: 姿态控制启动之后不需要一直开着这个窗口。

27 | 28 | 29 | -------------------------------------------------------------------------------- /resc/icon-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/icon-v2.png -------------------------------------------------------------------------------- /resc/main.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | material-icons.ttf 5 | 6 | 7 | splash.png 8 | 9 | 10 | icon-v2.png 11 | 12 | 13 | eye.9.png 14 | half-face.png 15 | half-face-mouth-open.png 16 | 17 | 18 | ../LICENSE 19 | ../LICENSE-CC-BY-SA 20 | PREAMBLE 21 | AGPL-BRIEF 22 | CC-BY-SA-BRIEF 23 | 24 | 25 | model/TestObject.obj 26 | model/TestObject.mtl 27 | model/DebugTexture.png 28 | model/DebugTextureNorm.png 29 | 30 | 31 | shader/empty/empty.vert 32 | shader/empty/empty.frag 33 | 34 | shader/common/emissive.vert 35 | shader/common/emissive.frag 36 | shader/standard/opaque.vert 37 | shader/standard/opaque.frag 38 | shader/standard/translucent.vert 39 | shader/standard/translucent.frag 40 | 41 | 42 | bis/interp.bis 43 | 44 | 45 | help/index.html 46 | help/error.html 47 | help/index.css 48 | help/pages/opengl.html 49 | help/pages/about.html 50 | help/pages/position.html 51 | help/pages/tracking.html 52 | help/pages/tracking/vts.html 53 | help/pages/tracking/osf.html 54 | help/pages/tracking/manual.html 55 | help/pages/body-anim.html 56 | help/pages/attachment.html 57 | help/pages/screen-anim.html 58 | help/pages/audio-analysis.html 59 | help/pages/advanced.html 60 | help/pages/extending/body-anim.html 61 | help/pages/extending/static-anim.html 62 | 63 | 64 | help/images/opengl.png 65 | help/images/position.png 66 | help/images/tracking/vts.png 67 | help/images/tracking/vts-accept.png 68 | help/images/tracking/vts-config.png 69 | help/images/tracking/vts-follow.png 70 | help/images/tracking/osf.png 71 | help/images/tracking/osf-config.png 72 | help/images/tracking/manual.png 73 | help/images/tracking/manual-audio.png 74 | help/images/tracking/manual-mouth.png 75 | help/images/body-anim.png 76 | help/images/body-anim-expand.png 77 | help/images/body-anim-spacium.png 78 | help/images/attachment.png 79 | help/images/attachment-spacium.png 80 | help/images/screen.png 81 | help/images/screen-audio.png 82 | help/images/screen-static-expand.png 83 | help/images/screen-anim-expand.png 84 | help/images/screen-anim-typewriter.png 85 | help/images/audio.png 86 | help/images/extra.png 87 | 88 | 89 | -------------------------------------------------------------------------------- /resc/material-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/material-icons.ttf -------------------------------------------------------------------------------- /resc/model/DebugTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/model/DebugTexture.png -------------------------------------------------------------------------------- /resc/model/DebugTextureHeight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/model/DebugTextureHeight.png -------------------------------------------------------------------------------- /resc/model/DebugTextureNorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/model/DebugTextureNorm.png -------------------------------------------------------------------------------- /resc/model/TestObject.mtl: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 MTL File: 'TestObject.blend' 2 | # www.blender.org 3 | 4 | newmtl TestMaterial 5 | Ns 250.000000 6 | Ka 0.5 0.5 0.5 7 | Kd 1 1 1 8 | Ks 0 0 0 9 | d 1.000000 10 | map_Kd DebugTexture.png 11 | bump DebugTextureNorm.png -------------------------------------------------------------------------------- /resc/model/TestObject.obj: -------------------------------------------------------------------------------- 1 | # Blender 3.3.1 2 | # www.blender.org 3 | mtllib TestObject.mtl 4 | o Cube 5 | v -5.000000 -5.000000 -5.000000 6 | v -5.000000 5.000000 -5.000000 7 | v 5.000000 -5.000000 -5.000000 8 | v 5.000000 5.000000 -5.000000 9 | v -5.000000 -5.000000 5.000000 10 | v -5.000000 5.000000 5.000000 11 | v 5.000000 -5.000000 5.000000 12 | v 5.000000 5.000000 5.000000 13 | vn -0.0000 -0.0000 -5.0000 14 | vn 5.0000 -0.0000 -0.0000 15 | vn -0.0000 -0.0000 5.0000 16 | vn -5.0000 -0.0000 -0.0000 17 | vn -0.0000 -5.0000 -0.0000 18 | vn -0.0000 5.0000 -0.0000 19 | vt 0.375000 0.000000 20 | vt 0.375000 1.000000 21 | vt 0.125000 0.750000 22 | vt 0.625000 0.000000 23 | vt 0.625000 1.000000 24 | vt 0.875000 0.750000 25 | vt 0.125000 0.500000 26 | vt 0.375000 0.250000 27 | vt 0.625000 0.250000 28 | vt 0.875000 0.500000 29 | vt 0.375000 0.750000 30 | vt 0.625000 0.750000 31 | vt 0.375000 0.500000 32 | vt 0.625000 0.500000 33 | s 0 34 | usemtl TestMaterial 35 | f 2/4/1 3/8/1 1/1/1 36 | f 4/9/2 7/13/2 3/8/2 37 | f 8/14/3 5/11/3 7/13/3 38 | f 6/12/4 1/2/4 5/11/4 39 | f 7/13/5 1/3/5 3/7/5 40 | f 4/10/6 6/12/6 8/14/6 41 | f 2/4/1 4/9/1 3/8/1 42 | f 4/9/2 8/14/2 7/13/2 43 | f 8/14/3 6/12/3 5/11/3 44 | f 6/12/4 2/5/4 1/2/4 45 | f 7/13/5 5/11/5 1/3/5 46 | f 4/10/6 2/6/6 6/12/6 47 | -------------------------------------------------------------------------------- /resc/shader/common/emissive.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec2 texCoord; 4 | 5 | uniform sampler2D screenTexture; 6 | 7 | out vec4 fragColor; 8 | 9 | void main() { 10 | vec4 color = texture(screenTexture, texCoord); 11 | fragColor = color; 12 | } 13 | -------------------------------------------------------------------------------- /resc/shader/common/emissive.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout(location = 0) in vec3 inVertexCoord; 4 | layout(location = 1) in vec2 inTexCoord; 5 | 6 | uniform mat4 projection; 7 | uniform mat4 modelView; 8 | 9 | out vec2 texCoord; 10 | 11 | void main() { 12 | gl_Position = projection * modelView * vec4(inVertexCoord, 1.0); 13 | texCoord = inTexCoord; 14 | } 15 | -------------------------------------------------------------------------------- /resc/shader/empty/empty.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 fragPos; 4 | in vec2 texCoord; 5 | 6 | struct Material { 7 | vec3 ambient; 8 | vec3 diffuse; 9 | vec3 specular; 10 | float shininess; 11 | }; 12 | 13 | uniform Material material; 14 | uniform sampler2D diffuseTex; 15 | uniform sampler2D normalTex; 16 | 17 | out vec4 fragColor; 18 | 19 | void main() { 20 | fragColor = texture(diffuseTex, texCoord); 21 | } 22 | -------------------------------------------------------------------------------- /resc/shader/empty/empty.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 inVertexCoord; 4 | layout (location = 1) in vec3 inVertexNormal; 5 | layout (location = 2) in vec2 inTexCoord; 6 | layout (location = 3) in vec3 inTangent; 7 | layout (location = 4) in vec3 inBiTangent; 8 | 9 | uniform mat4 projection; 10 | uniform mat4 modelView; 11 | 12 | out vec3 fragPos; 13 | out vec2 texCoord; 14 | 15 | void main() { 16 | fragPos = vec3(modelView * vec4(inVertexCoord, 1.0)); 17 | texCoord = vec2(inTexCoord.x, 1.0 - inTexCoord.y); 18 | 19 | gl_Position = projection * vec4(fragPos, 1.0); 20 | } 21 | -------------------------------------------------------------------------------- /resc/shader/standard/opaque.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | struct Light { 4 | vec3 ambient; 5 | vec3 diffuse; 6 | vec3 specular; 7 | }; 8 | 9 | const Light light = Light(vec3(1.0f), vec3(1.0f), vec3(1.0f)); 10 | 11 | in vec3 fragPos; 12 | in vec2 texCoord; 13 | in vec3 tangentLightPos; 14 | in vec3 tangentViewPos; 15 | in vec3 tangentFragPos; 16 | 17 | struct Material { 18 | vec4 ambient; 19 | vec4 diffuse; 20 | vec4 specular; 21 | float shininess; 22 | }; 23 | 24 | uniform Material material; 25 | uniform sampler2D diffuseTex; 26 | uniform sampler2D normalTex; 27 | 28 | out vec4 fragColor; 29 | 30 | void main() { 31 | vec3 normal = texture(normalTex, texCoord).rgb; 32 | normal = normalize(normal * 2.0 - 1.0); 33 | 34 | vec3 color = texture(diffuseTex, texCoord).rgb; 35 | vec3 ambient = light.ambient * vec3(material.ambient) * color; 36 | 37 | vec3 lightDir = normalize(tangentLightPos - tangentFragPos); 38 | float diff = max(dot(lightDir, normal), 0.0); 39 | vec3 diffuse = light.diffuse * vec3(material.diffuse) * diff * color; 40 | 41 | vec3 viewDir = normalize(tangentViewPos - tangentFragPos); 42 | vec3 reflectDir = reflect(-lightDir, normal); 43 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 44 | vec3 specular = light.specular * vec3(material.specular) * spec * color; 45 | 46 | fragColor = vec4(ambient + max(vec3(0.0), diffuse) + max(vec3(0.0), specular), 1.0f); 47 | } 48 | -------------------------------------------------------------------------------- /resc/shader/standard/opaque.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 inVertexCoord; 4 | layout (location = 1) in vec3 inVertexNormal; 5 | layout (location = 2) in vec2 inTexCoord; 6 | layout (location = 3) in vec3 inTangent; 7 | layout (location = 4) in vec3 inBiTangent; 8 | 9 | uniform mat4 projection; 10 | uniform mat4 modelView; 11 | 12 | const vec3 lightPos = vec3(0.0, 0.0, 0.0); 13 | const vec3 viewPos = vec3(0.0, 0.0, 0.0); 14 | 15 | out vec3 fragPos; 16 | out vec2 texCoord; 17 | out vec3 tangentLightPos; 18 | out vec3 tangentViewPos; 19 | out vec3 tangentFragPos; 20 | 21 | void main() { 22 | fragPos = vec3(modelView * vec4(inVertexCoord, 1.0)); 23 | texCoord = vec2(inTexCoord.x, 1.0 - inTexCoord.y); 24 | 25 | mat3 normalMatrix = transpose(inverse(mat3(modelView))); 26 | vec3 t = normalize(normalMatrix * inTangent); 27 | vec3 b = normalize(normalMatrix * inBiTangent); 28 | vec3 n = normalize(normalMatrix * inVertexNormal); 29 | mat3 tbn = mat3(t, b, n); 30 | 31 | tangentLightPos = tbn * lightPos; 32 | tangentViewPos = tbn * viewPos; 33 | tangentFragPos = tbn * fragPos; 34 | 35 | gl_Position = projection * vec4(fragPos, 1.0); 36 | } 37 | -------------------------------------------------------------------------------- /resc/shader/standard/translucent.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | struct Material { 4 | vec3 ambient; 5 | vec3 diffuse; 6 | vec3 specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 ambient; 12 | vec3 diffuse; 13 | vec3 specular; 14 | }; 15 | 16 | const Material material = Material( 17 | vec3(0.1f, 0.125f, 0.15f), 18 | vec3(0.1f, 0.1125f, 0.125f), 19 | vec3(0.1f, 0.1125f, 0.125f), 20 | 32.0f 21 | ); 22 | 23 | const Light light = Light(vec3(1.0f), vec3(1.0f), vec3(1.0f)); 24 | 25 | in vec3 fragPos; 26 | in vec3 normal; 27 | 28 | uniform vec3 light0Pos; 29 | uniform vec3 light1Pos; 30 | 31 | out vec4 fragColor; 32 | 33 | void main() { 34 | vec3 norm = normalize(normal); 35 | 36 | // ambient 37 | vec3 ambient = light.ambient * material.ambient; 38 | 39 | // diffuse 40 | vec3 lightDir0 = normalize(light0Pos - fragPos); 41 | vec3 lightDir1 = normalize(light1Pos - fragPos); 42 | float diff0 = max(dot(norm, lightDir0), 0.0); 43 | float diff1 = max(dot(norm, lightDir1), 0.0); 44 | vec3 diffuse0 = diff0 * material.diffuse * light.diffuse; 45 | vec3 diffuse1 = diff1 * material.diffuse * light.diffuse; 46 | 47 | // specular 48 | // our view point is always at the origin, thus the view direction is the negative position 49 | vec3 viewDir = normalize(-fragPos); 50 | vec3 reflectDir0 = reflect(-lightDir0, norm); 51 | vec3 reflectDir1 = reflect(-lightDir1, norm); 52 | float spec0 = pow(max(dot(viewDir, reflectDir0), 0.0), material.shininess); 53 | float spec1 = pow(max(dot(viewDir, reflectDir1), 0.0), material.shininess); 54 | vec3 specular0 = light.specular * (spec0 * material.specular); 55 | vec3 specular1 = light.specular * (spec1 * material.specular); 56 | 57 | // blending 58 | vec3 result = ambient + diffuse0 + diffuse1 + specular0 + specular1; 59 | fragColor = vec4(result, 1.0); 60 | } 61 | -------------------------------------------------------------------------------- /resc/shader/standard/translucent.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 inVertexCoord; 4 | layout (location = 1) in vec3 inNormal; 5 | 6 | uniform mat4 projection; 7 | uniform mat4 modelView; 8 | 9 | out vec3 fragPos; 10 | out vec3 normal; 11 | 12 | void main() { 13 | fragPos = vec3(modelView * vec4(inVertexCoord, 1.0)); 14 | normal = mat3(transpose(inverse(modelView))) * inNormal; 15 | 16 | gl_Position = projection * vec4(fragPos, 1.0); 17 | } 18 | -------------------------------------------------------------------------------- /resc/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/splash.png -------------------------------------------------------------------------------- /resc/win32/CWGLX.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CW_WIN32_RESOURCE 4 | #include "Version.h" 5 | 6 | 1 VERSIONINFO 7 | FILEVERSION CWGLX_FILE_VERSION 8 | PRODUCTVERSION WG_PRODUCT_VERSION 9 | FILEOS VOS_NT 10 | FILETYPE VFT_DLL 11 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 12 | #if defined(WG_PRIVATE_BUILD_INFO) 13 | FILEFLAGS VS_FF_PRIVATEBUILD 14 | #endif 15 | BEGIN 16 | BLOCK "StringFileInfo" 17 | BEGIN 18 | BLOCK "040904E4" 19 | BEGIN 20 | VALUE "ProductName", WG_PRODUCT_NAME 21 | VALUE "ProductVersion", WG_PRODUCT_VERSION_STRING 22 | VALUE "CompanyName", COMPANY_NAME 23 | VALUE "LegalCopyright", COPYRIGHT_INFO 24 | VALUE "FileDescription", "CWGLX OpenGL Helper Library" 25 | VALUE "FileVersion", CWGLX_FILE_VERSION_STRING 26 | VALUE "OriginalFilename", "CWGLX.dll" 27 | VALUE "InternalName", "CWGLX.dll" 28 | #if defined(WG_PRIVATE_BUILD_INFO) 29 | VALUE "PrivateBuild", WG_PRIVATE_BUILD_INFO 30 | #endif 31 | END 32 | END 33 | BLOCK "VarFileInfo" 34 | BEGIN 35 | VALUE "Translation", 0x0409, 0x04B0 36 | END 37 | END 38 | -------------------------------------------------------------------------------- /resc/win32/CWUtil.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CW_WIN32_RESOURCE 4 | #include "Version.h" 5 | 6 | 1 VERSIONINFO 7 | FILEVERSION CWUTIL_FILE_VERSION 8 | PRODUCTVERSION WG_PRODUCT_VERSION 9 | FILEOS VOS_NT 10 | FILETYPE VFT_DLL 11 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 12 | #if defined(WG_PRIVATE_BUILD_INFO) 13 | FILEFLAGS VS_FF_PRIVATEBUILD 14 | #endif 15 | BEGIN 16 | BLOCK "StringFileInfo" 17 | BEGIN 18 | BLOCK "040904E4" 19 | BEGIN 20 | VALUE "ProductName", WG_PRODUCT_NAME 21 | VALUE "ProductVersion", WG_PRODUCT_VERSION_STRING 22 | VALUE "CompanyName", COMPANY_NAME 23 | VALUE "LegalCopyright", COPYRIGHT_INFO 24 | VALUE "FileDescription", "CWUtil Utility Library" 25 | VALUE "FileVersion", CWUTIL_FILE_VERSION_STRING 26 | VALUE "OriginalFilename", "CWUtil.dll" 27 | VALUE "InternalName", "CWUtil.dll" 28 | #if defined(WG_PRIVATE_BUILD_INFO) 29 | VALUE "PrivateBuild", WG_PRIVATE_BUILD_INFO 30 | #endif 31 | END 32 | END 33 | BLOCK "VarFileInfo" 34 | BEGIN 35 | VALUE "Translation", 0x0409, 0x04B0 36 | END 37 | END 38 | -------------------------------------------------------------------------------- /resc/win32/Main.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CW_WIN32_RESOURCE 4 | #include "Version.h" 5 | 6 | 0 ICON DISCARDABLE "icon-v2.ico" 7 | 8 | 1 VERSIONINFO 9 | FILEVERSION WG_PRODUCT_VERSION 10 | PRODUCTVERSION WG_PRODUCT_VERSION 11 | FILEOS VOS_NT 12 | FILETYPE VFT_APP 13 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 14 | #if defined(WG_PRIVATE_BUILD_INFO) 15 | FILEFLAGS VS_FF_PRIVATEBUILD 16 | #endif 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "040904E4" 21 | BEGIN 22 | VALUE "ProductName", WG_PRODUCT_NAME 23 | VALUE "ProductVersion", WG_PRODUCT_VERSION_STRING 24 | VALUE "CompanyName", COMPANY_NAME 25 | VALUE "LegalCopyright", COPYRIGHT_INFO 26 | VALUE "FileDescription", "Project-WG Main Executable" 27 | VALUE "FileVersion", WG_PRODUCT_VERSION_STRING 28 | VALUE "OriginalFilename", "Project-WG.exe" 29 | #if defined(WG_PRIVATE_BUILD_INFO) 30 | VALUE "PrivateBuild", WG_PRIVATE_BUILD_INFO 31 | #endif 32 | END 33 | END 34 | BLOCK "VarFileInfo" 35 | BEGIN 36 | VALUE "Translation", 0x0409, 0x04B0 37 | END 38 | END 39 | -------------------------------------------------------------------------------- /resc/win32/icon-v2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/resc/win32/icon-v2.ico -------------------------------------------------------------------------------- /src/GlobalConfig.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "GlobalConfig.h" 4 | #include "util/FileUtil.h" 5 | #include "util/IniLoader.h" 6 | 7 | namespace cw { 8 | 9 | GlobalConfig GlobalConfig::Instance; 10 | 11 | void InitGlobalConfig() { 12 | QString iniFileContent = ReadToString("config.ini"); 13 | IniFileData config = IniFileData::Parse(iniFileContent); 14 | 15 | IniSection const* commonConfig = config.GetSection("common"); 16 | if (commonConfig) { 17 | GlobalConfig::Instance.stayOnTop = 18 | commonConfig->GetBoolValue("stay_on_top"); 19 | GlobalConfig::Instance.fillBackground = 20 | commonConfig->GetBoolValue("fill_background"); 21 | 22 | GlobalConfig::Instance.backgroundColor.r = 23 | commonConfig->GetFloatValue("background_r"); 24 | GlobalConfig::Instance.backgroundColor.g = 25 | commonConfig->GetFloatValue("background_g"); 26 | GlobalConfig::Instance.backgroundColor.b = 27 | commonConfig->GetFloatValue("background_b"); 28 | } 29 | 30 | IniSection const* renderConfig = config.GetSection("render"); 31 | if (renderConfig) { 32 | GlobalConfig::Instance.multisampling = 33 | renderConfig->GetBoolValue("multisampling"); 34 | GlobalConfig::Instance.multisamplingSamples = 35 | renderConfig->GetIntValue("multisampling_samples"); 36 | GlobalConfig::Instance.lineSmoothHint = 37 | renderConfig->GetBoolValue("line_smooth"); 38 | GlobalConfig::Instance.anisotropyFilter = 39 | renderConfig->GetBoolValue("anisotropy_filter"); 40 | GlobalConfig::Instance.linearSampling = 41 | renderConfig->GetBoolValue("linear_sampling"); 42 | } 43 | 44 | IniSection const* controlConfig = config.GetSection("control"); 45 | if (controlConfig) { 46 | QString defaultControlMode = controlConfig->GetData("default_mode").toLower(); 47 | if (defaultControlMode == "vts") { 48 | GlobalConfig::Instance.defaultControlMode = GlobalConfig::ControlMode::VTS; 49 | } else if (defaultControlMode == "osf") { 50 | GlobalConfig::Instance.defaultControlMode = GlobalConfig::ControlMode::OSF; 51 | } else if (defaultControlMode == "mp") { 52 | GlobalConfig::Instance.defaultControlMode = GlobalConfig::ControlMode::MP; 53 | } else if (defaultControlMode == "manual") { 54 | GlobalConfig::Instance.defaultControlMode = GlobalConfig::ControlMode::Manual; 55 | } else { 56 | GlobalConfig::Instance.defaultControlMode = GlobalConfig::ControlMode::None; 57 | } 58 | } 59 | 60 | IniSection const* vtsConfig = config.GetSection("control.vts"); 61 | if (vtsConfig) { 62 | GlobalConfig::Instance.vtsWebsocketPort = vtsConfig->GetIntValue("websocket_port"); 63 | } 64 | 65 | IniSection const* osfConfig = config.GetSection("control.osf"); 66 | if (osfConfig) { 67 | GlobalConfig::Instance.osfUdpPort = osfConfig->GetIntValue("udp_port"); 68 | GlobalConfig::Instance.osfCorrectionX = osfConfig->GetFloatValue("correction_x"); 69 | GlobalConfig::Instance.osfCorrectionY = osfConfig->GetFloatValue("correction_y"); 70 | GlobalConfig::Instance.osfCorrectionZ = osfConfig->GetFloatValue("correction_z"); 71 | GlobalConfig::Instance.osfSmooth = osfConfig->GetIntValue("smooth"); 72 | } 73 | } 74 | 75 | char const * 76 | GlobalConfig::ControlModeToString(GlobalConfig::ControlMode mode) { 77 | switch (mode) { 78 | case ControlMode::None: 79 | return "none"; 80 | case ControlMode::VTS: 81 | return "vts"; 82 | case ControlMode::OSF: 83 | return "osf"; 84 | case ControlMode::MP: 85 | return "mp"; 86 | case ControlMode::Manual: 87 | return "manual"; 88 | } 89 | } 90 | 91 | } // namespace cw 92 | -------------------------------------------------------------------------------- /src/cwglx/Base/ElementBufferObject.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/Base/ElementBufferObject.h" 2 | 3 | #include "cwglx/GL/GLImpl.h" 4 | 5 | namespace cw { 6 | 7 | ElementBufferObject::ElementBufferObject(GLFunctions *f) 8 | : m_Deleted(false) 9 | { 10 | f->glGenBuffers(1, &m_EBO); 11 | } 12 | 13 | ElementBufferObject::~ElementBufferObject() { 14 | if (!m_Deleted) { 15 | qWarning() << "ElementBufferObject::~ElementBufferObject():" 16 | << "element buffer object deleted before releasing relevant OpenGL resources"; 17 | } 18 | } 19 | 20 | void ElementBufferObject::Bind(GLFunctions *f) const noexcept { 21 | if (m_Deleted) { 22 | qWarning() << "ElementBufferObject::Bind(GLFunctions*):" 23 | << "cannot bind to an already deleted element buffer object"; 24 | return; 25 | } 26 | 27 | f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO); 28 | } 29 | 30 | void ElementBufferObject::Unbind(GLFunctions *f) const noexcept { 31 | Q_UNUSED(this) 32 | 33 | f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 34 | } 35 | 36 | void ElementBufferObject::BufferData(GLFunctions *f, 37 | const GLuint *data, 38 | std::size_t size, 39 | GLenum drawHint) const noexcept { 40 | if (m_Deleted) { 41 | qWarning() << "ElementBufferObject::Bind(GLFunctions*):" 42 | << "cannot provide data to an already deleted element buffer object"; 43 | return; 44 | } 45 | 46 | f->glBufferData(GL_ELEMENT_ARRAY_BUFFER, 47 | static_cast(size * sizeof(GLuint)), 48 | data, drawHint); 49 | } 50 | 51 | void ElementBufferObject::Delete(GLFunctions *f) { 52 | if (m_Deleted) { 53 | return; 54 | } 55 | 56 | f->glDeleteBuffers(1, &m_EBO); 57 | m_Deleted = true; 58 | } 59 | 60 | } // namespace cw 61 | -------------------------------------------------------------------------------- /src/cwglx/Base/Shader.cc: -------------------------------------------------------------------------------- 1 | #include "include/cwglx/Base/Shader.h" 2 | 3 | #include 4 | #include "include/cwglx/GL/GLImpl.h" 5 | #include "wgc0310/Shader.h" 6 | 7 | 8 | namespace cw { 9 | 10 | Shader::Shader(QString programText, GLenum shaderType) 11 | : m_ProgramText(std::move(programText)), 12 | m_ShaderType(shaderType), 13 | m_ShaderId(0), 14 | m_Compiled(false) 15 | {} 16 | 17 | Shader::~Shader() { 18 | if (m_Compiled) { 19 | qWarning() << "Shader::~Shader():" 20 | << "shader object deleted before releasing relevant OpenGL resources"; 21 | } 22 | } 23 | 24 | bool Shader::Compile(GLFunctions *f) { 25 | if (m_Compiled) { 26 | return true; 27 | } 28 | 29 | std::string programText = m_ProgramText.toStdString(); 30 | const char *rawProgramText = programText.data(); 31 | 32 | m_ShaderId = f->glCreateShader(m_ShaderType); 33 | f->glShaderSource(m_ShaderId, 1, &rawProgramText, nullptr); 34 | f->glCompileShader(m_ShaderId); 35 | 36 | GLint success; 37 | f->glGetShaderiv(m_ShaderId, GL_COMPILE_STATUS, &success); 38 | if (!success) { 39 | GLint logLength; 40 | f->glGetShaderiv(m_ShaderId, GL_INFO_LOG_LENGTH, &logLength); 41 | 42 | char *buffer = new char[logLength + 1]; 43 | f->glGetShaderInfoLog(m_ShaderId, logLength, nullptr, buffer); 44 | m_CompileError = QString::fromUtf8(buffer); 45 | delete[] buffer; 46 | 47 | f->glDeleteShader(m_ShaderId); 48 | return false; 49 | } 50 | 51 | m_Compiled = true; 52 | return true; 53 | } 54 | 55 | void Shader::Delete(GLFunctions *f) { 56 | if (m_Compiled) { 57 | f->glDeleteShader(m_ShaderId); 58 | m_Compiled = false; 59 | } 60 | } 61 | 62 | QString Shader::GetCompileError() const { 63 | return m_CompileError; 64 | } 65 | 66 | bool Shader::IsReady() const { 67 | return m_Compiled; 68 | } 69 | 70 | GLuint Shader::GetShaderId() const { 71 | return m_ShaderId; 72 | } 73 | 74 | } // namespace cw 75 | -------------------------------------------------------------------------------- /src/cwglx/Base/Texture.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/Base/Texture.h" 2 | 3 | #include 4 | #include "cwglx/GL/GLImpl.h" 5 | 6 | namespace cw { 7 | 8 | Texture2D::Texture2D(const QImage &image, 9 | GLFunctions *f, 10 | bool linearSampling, 11 | bool anisotropyFilter) 12 | : m_TextureId(0), 13 | m_IsDeleted(false) 14 | { 15 | QImage rgbaImage = image.convertToFormat(QImage::Format_RGBA8888); 16 | 17 | f->glGenTextures(1, &m_TextureId); 18 | f->glBindTexture(GL_TEXTURE_2D, m_TextureId); 19 | 20 | if (anisotropyFilter) { 21 | GLfloat maxAnisotropy = 1.0f; 22 | f->glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); 23 | f->glTexParameterf(GL_TEXTURE_2D, 24 | GL_TEXTURE_MAX_ANISOTROPY_EXT, 25 | maxAnisotropy); 26 | } 27 | 28 | if (linearSampling) { 29 | f->glTexParameteri(GL_TEXTURE_2D, 30 | GL_TEXTURE_MAG_FILTER, 31 | GL_LINEAR); 32 | f->glTexParameteri(GL_TEXTURE_2D, 33 | GL_TEXTURE_MIN_FILTER, 34 | GL_LINEAR_MIPMAP_LINEAR); 35 | } else { 36 | f->glTexParameteri(GL_TEXTURE_2D, 37 | GL_TEXTURE_MAG_FILTER, 38 | GL_NEAREST); 39 | f->glTexParameteri(GL_TEXTURE_2D, 40 | GL_TEXTURE_MIN_FILTER, 41 | GL_NEAREST); 42 | } 43 | 44 | f->glTexImage2D(GL_TEXTURE_2D, 45 | 0, 46 | GL_RGBA, 47 | rgbaImage.width(), 48 | rgbaImage.height(), 49 | 0, 50 | GL_RGBA, 51 | GL_UNSIGNED_BYTE, 52 | rgbaImage.bits()); 53 | 54 | if (linearSampling) { 55 | f->glGenerateMipmap(GL_TEXTURE_2D); 56 | } 57 | 58 | GLenum error = f->glGetError(); 59 | if (error != GL_NO_ERROR) { 60 | qCritical() << "Texture2D::Texture2D: failed loading texture:" << error; 61 | std::abort(); 62 | } 63 | } 64 | 65 | GLuint Texture2D::GetTextureId() const noexcept { 66 | Q_ASSERT(!m_IsDeleted && "Texture2D has been deleted"); 67 | return m_TextureId; 68 | } 69 | 70 | void Texture2D::ActivateTexture(GLFunctions *f, 71 | GLenum textureUnit, 72 | GLint uniform) const noexcept 73 | { 74 | Q_ASSERT(!m_IsDeleted && "Texture2D has been deleted"); 75 | f->glActiveTexture(textureUnit); 76 | f->glBindTexture(GL_TEXTURE_2D, m_TextureId); 77 | if (uniform >= 0) { 78 | f->glUniform1i(uniform, static_cast(textureUnit) - GL_TEXTURE0); 79 | } 80 | } 81 | 82 | void Texture2D::Delete(GLFunctions *f) noexcept { 83 | Q_ASSERT(!m_IsDeleted && "Texture2D has been deleted"); 84 | 85 | f->glDeleteTextures(1, &m_TextureId); 86 | m_IsDeleted = true; 87 | } 88 | 89 | Texture2D::~Texture2D() noexcept { 90 | if (!m_IsDeleted) { 91 | qWarning() << "Texture2D::~Texture2D():" 92 | << "texture deleted before releasing relevant OpenGL resources"; 93 | } 94 | } 95 | 96 | } // namespace cw 97 | -------------------------------------------------------------------------------- /src/cwglx/Base/VertexArrayObject.cc: -------------------------------------------------------------------------------- 1 | #include "include/cwglx/Base/VertexArrayObject.h" 2 | #include "include/cwglx/GL/GLImpl.h" 3 | 4 | namespace cw { 5 | VertexArrayObject::VertexArrayObject(GLFunctions *f) 6 | : m_VAO(0), 7 | m_Deleted(false) 8 | { 9 | f->glGenVertexArrays(1, &m_VAO); 10 | } 11 | 12 | VertexArrayObject::VertexArrayObject(GLuint vao, Sinkrate) 13 | : m_VAO(vao), 14 | m_Deleted(false) 15 | {} 16 | 17 | VertexArrayObject::~VertexArrayObject() { 18 | if (!m_Deleted) { 19 | qWarning() << "VertexArrayObject::~VertexArrayObject():" 20 | << "vertex array object deleted before releasing relevant OpenGL resources"; 21 | } 22 | } 23 | 24 | void VertexArrayObject::Bind(GLFunctions *f) const { 25 | if (m_Deleted) { 26 | qWarning() << "VertexArrayObject::Bind(GLFunctions*):" 27 | << "cannot bind an already deleted vertex array object"; 28 | return; 29 | } 30 | f->glBindVertexArray(m_VAO); 31 | } 32 | 33 | void VertexArrayObject::Unbind(GLFunctions *f) const { 34 | Q_UNUSED(this) 35 | 36 | f->glBindVertexArray(0); 37 | } 38 | 39 | void VertexArrayObject::Delete(GLFunctions *f) { 40 | if (m_Deleted) { 41 | return; 42 | } 43 | 44 | f->glDeleteVertexArrays(1, &m_VAO); 45 | m_Deleted = true; 46 | } 47 | 48 | std::vector> 49 | VertexArrayObject::CreateMany(GLFunctions *f, GLsizei count) { 50 | std::vector> ret{}; 51 | ret.reserve(count); 52 | 53 | std::vector vaoIds(count, 0); 54 | f->glGenVertexArrays(count, vaoIds.data()); 55 | 56 | for (auto &vaoId : vaoIds) { 57 | ret.push_back(std::make_unique( 58 | vaoId, 59 | SecretInternalsDoNotUseOrYouWillBeFired 60 | )); 61 | } 62 | 63 | return ret; 64 | } 65 | 66 | } // namespace cw 67 | -------------------------------------------------------------------------------- /src/cwglx/GL/GLInfo.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/GL/GLInfo.h" 2 | #include "cwglx/GL/GLImpl.h" 3 | 4 | namespace cw { 5 | 6 | GLInfo::GLInfo(const char *vendor, 7 | const char *version, 8 | const char *renderer, 9 | QString extensions) 10 | : vendor(vendor), 11 | version(version), 12 | renderer(renderer), 13 | extensions(std::move(extensions)) 14 | {} 15 | 16 | GLInfo GLInfo::AutoDetect(GLFunctions *f) { 17 | const char *vendor = reinterpret_cast(f->glGetString(GL_VENDOR)); 18 | const char *version = reinterpret_cast(f->glGetString(GL_VERSION)); 19 | const char *renderer = reinterpret_cast(f->glGetString(GL_RENDERER)); 20 | 21 | GLint numExtensions = 0; 22 | f->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); 23 | 24 | QStringList extensions; 25 | for (GLint i = 0; i < numExtensions; i++) { 26 | const char *extension = 27 | reinterpret_cast(f->glGetStringi(GL_EXTENSIONS, i)); 28 | extensions.push_back(extension); 29 | } 30 | 31 | return GLInfo { vendor, version, renderer, extensions.join(' ') }; 32 | } 33 | 34 | } // namespace cw 35 | -------------------------------------------------------------------------------- /src/cwglx/Object/Material.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuigda/Project-WG/e6c204bac738aca00e7e092faaa775b96955a7b0/src/cwglx/Object/Material.cc -------------------------------------------------------------------------------- /src/cwglx/Object/Object.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/Object/Object.h" 2 | 3 | #include 4 | #include "cwglx/GL/GLImpl.h" 5 | #include "cwglx/Base/ShaderProgram.h" 6 | 7 | namespace cw { 8 | 9 | void GLObjectContext::RemoveAll(GLFunctions *f) { 10 | for (auto &[name, texture] : m_TextureLibrary) { 11 | texture->Delete(f); 12 | } 13 | m_MaterialLibrary.clear(); 14 | m_TextureLibrary.clear(); 15 | } 16 | 17 | void GLObjectContext::Delete(GLFunctions *f) { 18 | for (auto &[name, texture] : m_TextureLibrary) { 19 | texture->Delete(f); 20 | } 21 | } 22 | 23 | bool GLObjectContext::HasTexture(QString const& texturePath) const { 24 | return m_TextureLibrary.contains(texturePath); 25 | } 26 | 27 | bool GLObjectContext::HasMaterial(QString const& materialName) const { 28 | return m_MaterialLibrary.contains(materialName); 29 | } 30 | 31 | Texture2D const* 32 | GLObjectContext::AddTexture(QString texturePath, 33 | std::unique_ptr &&texture) 34 | { 35 | auto it = m_TextureLibrary.find(texturePath); 36 | 37 | if (it != m_TextureLibrary.cend()) { 38 | qWarning() << "GLObjectContext::AddTexture(QString, std::unique_ptr&&):" 39 | << "texture" 40 | << texturePath 41 | << "has been added (same-path)"; 42 | return it->second.get(); 43 | } 44 | 45 | auto r = m_TextureLibrary.insert(std::make_pair<>( 46 | std::move(texturePath), 47 | std::move(texture)) 48 | ); 49 | return r.first->second.get(); 50 | } 51 | 52 | Material const* 53 | GLObjectContext::AddMaterial(QString materialName, 54 | std::unique_ptr &&material) 55 | { 56 | auto it = m_MaterialLibrary.find(materialName); 57 | 58 | if (it != m_MaterialLibrary.cend()) { 59 | qWarning() << "GLObjectContext::AddMaterial(QString, std::unique_ptr&&):" 60 | << "material" 61 | << materialName 62 | << "has been added (same-name)"; 63 | return it->second.get(); 64 | } 65 | 66 | auto r = m_MaterialLibrary.insert(std::make_pair<>( 67 | std::move(materialName), 68 | std::move(material) 69 | )); 70 | return r.first->second.get(); 71 | } 72 | 73 | Texture2D const *GLObjectContext::GetTexture(const QString &texturePath) const { 74 | auto it = m_TextureLibrary.find(texturePath); 75 | if (it == m_TextureLibrary.cend()) { 76 | qWarning() << "GLObjectContext::GetTexture(QString const&):" 77 | << "texture" 78 | << texturePath 79 | << "has not been loaded"; 80 | return nullptr; 81 | } 82 | return it->second.get(); 83 | } 84 | 85 | Material const *GLObjectContext::GetMaterial(const QString &materialName) const { 86 | auto it = m_MaterialLibrary.find(materialName); 87 | if (it == m_MaterialLibrary.cend()) { 88 | qWarning() << "GLObjectContext::GetMaterial(QString const&):" 89 | << "material" 90 | << materialName 91 | << "has not been defined"; 92 | return nullptr; 93 | } 94 | return it->second.get(); 95 | } 96 | 97 | GLObject::GLObject(std::unique_ptr &&vao, 98 | std::unique_ptr &&vbo, 99 | GLsizei vertexCount, 100 | const Material *material) 101 | : vao(std::move(vao)), 102 | vbo(std::move(vbo)), 103 | vertexCount(vertexCount), 104 | material(material) 105 | {} 106 | 107 | void GLObject::Draw(GLFunctions *f, ShaderProgram *shaderProgram) const { 108 | shaderProgram->SetUniform(f, QStringLiteral("material.ambient"), material->ambient); 109 | shaderProgram->SetUniform(f, QStringLiteral("material.diffuse"), material->diffuse); 110 | shaderProgram->SetUniform(f, QStringLiteral("material.specular"), material->specular); 111 | shaderProgram->SetUniform(f, QStringLiteral("material.shininess"), material->shine); 112 | 113 | if (material->diffuseTexture) { 114 | material->diffuseTexture->ActivateTexture( 115 | f, 116 | GL_TEXTURE0, 117 | shaderProgram->GetUniformLocation(f, QStringLiteral("diffuseTex")) 118 | ); 119 | } 120 | 121 | if (material->normalTexture) { 122 | material->normalTexture->ActivateTexture( 123 | f, 124 | GL_TEXTURE1, 125 | shaderProgram->GetUniformLocation(f, QStringLiteral("normalTex")) 126 | ); 127 | } 128 | 129 | vao->Bind(f); 130 | f->glDrawArrays(GL_TRIANGLES, 0, vertexCount); 131 | } 132 | 133 | void GLObject::Delete(GLFunctions *f) const { 134 | vao->Delete(f); 135 | vbo->Delete(f); 136 | } 137 | 138 | } // namespace cw 139 | -------------------------------------------------------------------------------- /src/cwglx/Object/Vertex.cc: -------------------------------------------------------------------------------- 1 | #include "include/cwglx/Object/Vertex.h" 2 | #include "include/cwglx/Base/VertexBufferObjectImpl.h" 3 | 4 | namespace cw { 5 | 6 | template class CW_DEFINE_VBO_TYPE(PlainVertex, vertexCoord); 7 | template class CW_DEFINE_VBO_TYPE(SimpleVertex, vertexCoord, vertexNormal); 8 | template class CW_DEFINE_VBO_TYPE(Vertex, vertexCoord, vertexNormal, texCoord, tangent, biTangent); 9 | 10 | } // namespace cw 11 | -------------------------------------------------------------------------------- /src/cwglx/Setup.cc: -------------------------------------------------------------------------------- 1 | #include "cwglx/Setup.h" 2 | #include "include/cwglx/GL/GLImpl.h" 3 | 4 | void cw::SetupPreferred(GLFunctions *f) { 5 | f->initializeOpenGLFunctions(); 6 | 7 | f->glFrontFace(GL_CCW); 8 | f->glDepthFunc(GL_LESS); 9 | f->glEnable(GL_CULL_FACE); 10 | f->glEnable(GL_DEPTH_TEST); 11 | 12 | f->glEnable(GL_BLEND); 13 | f->glBlendFuncSeparate(GL_ONE, 14 | GL_ONE_MINUS_SRC_ALPHA, 15 | GL_ONE, 16 | GL_ONE_MINUS_SRC_ALPHA); 17 | f->glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); 18 | } 19 | -------------------------------------------------------------------------------- /src/ui_next/CodeEdit.cc: -------------------------------------------------------------------------------- 1 | #include "ui_next/CodeEdit.h" 2 | 3 | #include 4 | #include 5 | 6 | CodeEdit::CodeEdit(QWidget *parent) 7 | : QTextEdit(parent) 8 | { 9 | setAcceptRichText(false); 10 | } 11 | 12 | void CodeEdit::keyPressEvent(QKeyEvent *event) { 13 | switch (event->key()) { 14 | case Qt::Key_Tab: { 15 | insertPlainText(" "); 16 | break; 17 | } 18 | case Qt::Key_Return: 19 | case Qt::Key_Enter: { 20 | QTextCursor cursor = textCursor(); 21 | QString text = cursor.block().text(); 22 | qsizetype pos = cursor.positionInBlock(); 23 | qsizetype count = 0; 24 | while (count < text.size() && count < pos && text.at(count).isSpace()) { 25 | count++; 26 | } 27 | 28 | cursor.insertText("\n"); 29 | for (int j = 0; j < count; j++) { 30 | cursor.insertText(" "); 31 | } 32 | break; 33 | } 34 | default: { 35 | QTextEdit::keyPressEvent(event); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ui_next/EntityControl.cc: -------------------------------------------------------------------------------- 1 | #include "ui_next/EntityControl.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "include/ui_next/EntityStatus.h" 11 | 12 | static QLayout* CreateSliderSuite(QString const& suiteName, 13 | EntityControl *cameraControl, 14 | GLfloat *controlledValue, 15 | int min, 16 | int max, 17 | int stepValue) { 18 | QHBoxLayout *layout = new QHBoxLayout(); 19 | 20 | QFont monospaceFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); 21 | QLabel *nameLabel = new QLabel(suiteName); 22 | nameLabel->setFont(monospaceFont); 23 | nameLabel->setFixedWidth(32); 24 | 25 | QSlider *slider = new QSlider(); 26 | slider->setOrientation(Qt::Horizontal); 27 | slider->setMinimum(min / stepValue); 28 | slider->setMaximum(max / stepValue); 29 | 30 | QLabel *valueLabel = new QLabel("0"); 31 | valueLabel->setFont(monospaceFont); 32 | valueLabel->setFixedWidth(32); 33 | QObject::connect( 34 | slider, 35 | &QSlider::valueChanged, 36 | valueLabel, 37 | [valueLabel, controlledValue, stepValue] (int value) { 38 | *controlledValue = static_cast(value * stepValue); 39 | valueLabel->setText(QString::number(value * stepValue)); 40 | } 41 | ); 42 | 43 | QObject::connect( 44 | cameraControl, 45 | &EntityControl::ResetEntityStatus, 46 | slider, 47 | [slider, controlledValue, stepValue] () { 48 | slider->setValue(static_cast(*controlledValue) / stepValue); 49 | } 50 | ); 51 | 52 | layout->addWidget(nameLabel); 53 | layout->addWidget(slider); 54 | layout->addWidget(valueLabel); 55 | return layout; 56 | } 57 | 58 | EntityControl::EntityControl(EntityStatus *status) noexcept 59 | : m_EntityStatus(status) 60 | { 61 | setWindowTitle("物体位置"); 62 | 63 | QVBoxLayout *mainLayout = new QVBoxLayout(); 64 | this->setLayout(mainLayout); 65 | 66 | { 67 | QGroupBox *cameraGroupBox = new QGroupBox("位移"); 68 | QVBoxLayout *layout = new QVBoxLayout(); 69 | cameraGroupBox->setLayout(layout); 70 | QLayout *x = CreateSliderSuite("X", this, &m_EntityStatus->translateX, -100, 100, 5); 71 | QLayout *y = CreateSliderSuite("Y", this, &m_EntityStatus->translateY, 0, 150, 5); 72 | QLayout *z = CreateSliderSuite("Z", this, &m_EntityStatus->translateZ, 0, 150, 5); 73 | layout->addLayout(x); 74 | layout->addLayout(y); 75 | layout->addLayout(z); 76 | 77 | mainLayout->addWidget(cameraGroupBox); 78 | } 79 | 80 | { 81 | QGroupBox *entityGroupBox = new QGroupBox("旋转"); 82 | QVBoxLayout *layout = new QVBoxLayout(); 83 | entityGroupBox->setLayout(layout); 84 | QLayout *x = CreateSliderSuite("X", this, &m_EntityStatus->entityRotateX, -360, 360, 10); 85 | QLayout *y = CreateSliderSuite("Y", this, &m_EntityStatus->entityRotateY, -360, 360, 10); 86 | QLayout *z = CreateSliderSuite("Z", this, &m_EntityStatus->entityRotateZ, -360, 360, 10); 87 | layout->addLayout(x); 88 | layout->addLayout(y); 89 | layout->addLayout(z); 90 | 91 | mainLayout->addWidget(entityGroupBox); 92 | } 93 | 94 | { 95 | QHBoxLayout *resetBox = new QHBoxLayout(); 96 | resetBox->addStretch(); 97 | QPushButton *pushButton = new QPushButton("重置"); 98 | resetBox->addWidget(pushButton); 99 | mainLayout->addLayout(resetBox); 100 | 101 | connect( 102 | pushButton, 103 | &QPushButton::clicked, 104 | this, 105 | [this] { 106 | this->m_EntityStatus->Reset(); 107 | emit this->ResetEntityStatus(); 108 | } 109 | ); 110 | } 111 | 112 | emit this->ResetEntityStatus(); 113 | 114 | setMinimumWidth(400); 115 | #pragma clang diagnostic push 116 | #pragma ide diagnostic ignored "VirtualCallInCtorOrDtor" 117 | // This should be safe since base class `QWidget` has been initialised, 118 | // and we did not reimplement `sizeHint` 119 | setFixedHeight(sizeHint().height()); 120 | #pragma clang diagnostic pop 121 | } 122 | -------------------------------------------------------------------------------- /src/ui_next/HelpBox.cc: -------------------------------------------------------------------------------- 1 | #include "ui_next/HelpBox.h" 2 | #include "util/FileUtil.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class TextBrowser : public QTextBrowser { 14 | public: 15 | explicit TextBrowser(QWidget *parent = nullptr) 16 | : QTextBrowser(parent) 17 | { 18 | setContextMenuPolicy(Qt::NoContextMenu); 19 | setContentsMargins(0, 8, 0, 0); 20 | } 21 | 22 | protected: 23 | void paintEvent(QPaintEvent *e) override { 24 | QPainter painter(viewport()); 25 | painter.setRenderHints(QPainter::Antialiasing 26 | | QPainter::TextAntialiasing 27 | | QPainter::SmoothPixmapTransform); 28 | 29 | const int xOffset = horizontalScrollBar()->value(); 30 | const int yOffset = verticalScrollBar()->value(); 31 | 32 | QRect r = e->rect(); 33 | painter.translate(-xOffset, -yOffset); 34 | r.translate(xOffset, yOffset); 35 | 36 | document()->drawContents(&painter, r); 37 | } 38 | }; 39 | 40 | HelpBox::HelpBox(QWidget *parent) 41 | : CloseSignallingWidget(parent) 42 | { 43 | this->setWindowTitle("帮助查看器"); 44 | this->resize(600, 600); 45 | 46 | QVBoxLayout *layout = new QVBoxLayout(); 47 | layout->setContentsMargins(3, 3, 3, 3); 48 | layout->setSpacing(3); 49 | this->setLayout(layout); 50 | 51 | QHBoxLayout *navigationLine = new QHBoxLayout(); 52 | layout->addLayout(navigationLine); 53 | 54 | QPushButton *homePage = new QPushButton("主页"); 55 | homePage->setFixedWidth(48); 56 | QPushButton *backward = new QPushButton("◀"); 57 | backward->setEnabled(false); 58 | backward->setFixedWidth(24); 59 | QPushButton *forward = new QPushButton("▶"); 60 | forward->setEnabled(false); 61 | forward->setFixedWidth(24); 62 | 63 | navigationLine->addWidget(homePage); 64 | navigationLine->addStretch(); 65 | navigationLine->addWidget(backward); 66 | navigationLine->addWidget(forward); 67 | 68 | TextBrowser *browser = new TextBrowser(); 69 | browser->setOpenExternalLinks(true); 70 | 71 | layout->addWidget(browser); 72 | 73 | connect(homePage, &QPushButton::clicked, browser, [browser] { 74 | browser->setSource(QUrl("qrc:/help/index.html")); 75 | }); 76 | 77 | connect(backward, &QPushButton::clicked, browser, [browser] { 78 | browser->backward(); 79 | }); 80 | 81 | connect(forward, &QPushButton::clicked, browser, [browser] { 82 | browser->forward(); 83 | }); 84 | 85 | connect(browser, &QTextBrowser::backwardAvailable, backward, &QPushButton::setEnabled); 86 | connect(browser, &QTextBrowser::forwardAvailable, forward, &QPushButton::setEnabled); 87 | 88 | connect(browser, &QTextBrowser::sourceChanged, this, [this, browser] { 89 | this->setWindowTitle("帮助查看器 - " + browser->documentTitle()); 90 | }); 91 | 92 | browser->document()->setDefaultStyleSheet(cw::ReadToString(":/help/index.css")); 93 | browser->setSource(QUrl("qrc:/help/index.html"), QTextDocument::HtmlResource); 94 | } 95 | -------------------------------------------------------------------------------- /src/ui_next/SearchDialog.cc: -------------------------------------------------------------------------------- 1 | #include "ui_next/SearchDialog.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | SearchDialog::SearchDialog(QPlainTextEdit *textEdit, CloseSignallingWidget *parent) 9 | : QWidget(parent, Qt::Window), 10 | m_TextEdit(textEdit) 11 | { 12 | setWindowTitle("搜索"); 13 | 14 | QHBoxLayout *layout = new QHBoxLayout(this); 15 | setLayout(layout); 16 | 17 | QLineEdit *lineEdit = new QLineEdit(); 18 | layout->addWidget(lineEdit); 19 | 20 | QPushButton *button = new QPushButton("搜索"); 21 | layout->addWidget(button); 22 | 23 | connect(button, &QPushButton::clicked, m_TextEdit, [this, lineEdit] { 24 | QString text = lineEdit->text().trimmed(); 25 | if (text.isEmpty()) { 26 | return; 27 | } 28 | 29 | if (!m_TextEdit->find(text)) { 30 | QTextCursor cursor = m_TextEdit->textCursor(); 31 | cursor.movePosition(QTextCursor::Start); 32 | m_TextEdit->setTextCursor(cursor); 33 | if (!m_TextEdit->find(text)) { 34 | QMessageBox::warning(this, "搜索", "没有找到指定的文本"); 35 | } 36 | } 37 | }); 38 | 39 | connect(parent, &CloseSignallingWidget::AboutToClose, this, &QWidget::close); 40 | 41 | #pragma clang diagnostic push 42 | #pragma ide diagnostic ignored "VirtualCallInCtorOrDtor" 43 | // This should be safe since base class `QWidget` has been initialised, 44 | // and we did not reimplement `sizeHint` 45 | QSize size = sizeHint(); 46 | #pragma clang diagnostic pop 47 | setFixedSize(500, size.height()); 48 | } 49 | -------------------------------------------------------------------------------- /src/ui_next/track/FaceTrackControl.cc: -------------------------------------------------------------------------------- 1 | #include "ui_next/FaceTrackControl.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include "TrackControlImpl.h" 7 | 8 | TrackControl::TrackControl(wgc0310::HeadStatus *headStatus, 9 | wgc0310::ScreenDisplayMode *screenDisplayMode, 10 | QThread *workerThread) 11 | : CloseSignallingWidget(nullptr, Qt::Window), 12 | m_HeadStatus(headStatus), 13 | m_ScreenDisplayMode(screenDisplayMode), 14 | m_WorkerThread(workerThread) 15 | { 16 | this->setWindowTitle("姿态控制"); 17 | 18 | QVBoxLayout *mainLayout = new QVBoxLayout(); 19 | this->setLayout(mainLayout); 20 | 21 | QHBoxLayout *modeSelectBox = new QHBoxLayout(); 22 | modeSelectBox->addWidget(new QLabel("模式选择")); 23 | modeSelectBox->addStretch(); 24 | 25 | QRadioButton *vtsMode = new QRadioButton("VTS"); 26 | vtsMode->setChecked(true); 27 | modeSelectBox->addWidget(vtsMode); 28 | 29 | QRadioButton *osfMode = new QRadioButton("OSF"); 30 | modeSelectBox->addWidget(osfMode); 31 | 32 | QRadioButton *mediaPipeMode = new QRadioButton("MediaPipe"); 33 | modeSelectBox->addWidget(mediaPipeMode); 34 | 35 | QRadioButton *manualMode = new QRadioButton("手动控制"); 36 | modeSelectBox->addWidget(manualMode); 37 | 38 | mainLayout->addLayout(modeSelectBox); 39 | 40 | m_VTSTrackControl = new VTSTrackControl(m_HeadStatus, m_WorkerThread); 41 | mainLayout->addWidget(m_VTSTrackControl); 42 | 43 | m_OSFTrackControl = new OSFTrackControl(m_HeadStatus, m_WorkerThread); 44 | m_OSFTrackControl->setVisible(false); 45 | mainLayout->addWidget(m_OSFTrackControl); 46 | 47 | m_ManualTrackControl = new ManualTrackControl(m_HeadStatus, m_ScreenDisplayMode); 48 | m_ManualTrackControl->setVisible(false); 49 | mainLayout->addWidget(m_ManualTrackControl); 50 | 51 | connect( 52 | vtsMode, 53 | &QRadioButton::toggled, 54 | this, 55 | [this] (bool toggled) { 56 | if (toggled) { 57 | m_VTSTrackControl->show(); 58 | } else { 59 | m_VTSTrackControl->StopTracking(); 60 | m_VTSTrackControl->hide(); 61 | } 62 | setFixedSize(minimumSizeHint()); 63 | } 64 | ); 65 | 66 | connect( 67 | osfMode, 68 | &QRadioButton::toggled, 69 | this, 70 | [this] (bool toggled) { 71 | if (toggled) { 72 | m_OSFTrackControl->show(); 73 | } else { 74 | m_OSFTrackControl->StopTracking(); 75 | m_OSFTrackControl->hide(); 76 | } 77 | setFixedSize(minimumSizeHint()); 78 | } 79 | ); 80 | 81 | connect( 82 | manualMode, 83 | &QRadioButton::toggled, 84 | this, 85 | [this] (bool toggled) { 86 | if (toggled) { 87 | m_ManualTrackControl->show(); 88 | } else { 89 | m_ManualTrackControl->hide(); 90 | } 91 | setFixedSize(minimumSizeHint()); 92 | } 93 | ); 94 | 95 | #pragma clang diagnostic push 96 | #pragma ide diagnostic ignored "VirtualCallInCtorOrDtor" 97 | // This should be safe since base class `QWidget` has been initialised, 98 | // and we did not reimplement `sizeHint` 99 | setFixedSize(sizeHint()); 100 | #pragma clang diagnostic pop 101 | } 102 | -------------------------------------------------------------------------------- /src/ui_next/track/MPTrackControl.cc: -------------------------------------------------------------------------------- 1 | #include "TrackControlImpl.h" 2 | 3 | #include 4 | #include "wgc0310/HeadStatus.h" 5 | 6 | void MPTrackControl::HandleError(const QString& error) { 7 | QMessageBox::warning(this, "MediaPipe 面部/姿态捕捉错误", error); 8 | } 9 | 10 | void MPTrackControl::HandleHeadStatus(wgc0310::HeadStatus headStatus) { 11 | *m_HeadStatus = headStatus; 12 | } 13 | -------------------------------------------------------------------------------- /src/ui_next/track/TrackControlImpl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROJECT_WG_UINEXT_TRACK_CONTROL_IMPL_H 2 | #define PROJECT_WG_UINEXT_TRACK_CONTROL_IMPL_H 3 | 4 | #include "ui_next/FaceTrackControl.h" 5 | #include 6 | 7 | class QLabel; 8 | 9 | class VTSTrackControl : public QWidget { 10 | Q_OBJECT 11 | 12 | public: 13 | VTSTrackControl(wgc0310::HeadStatus *headStatus, 14 | QThread *workerThread, 15 | QWidget *parent = nullptr); 16 | 17 | signals: 18 | #pragma clang diagnostic push 19 | #pragma ide diagnostic ignored "NotImplementedFunctions" 20 | void StartTracking(quint16 port); 21 | void StopTracking(); 22 | #pragma clang diagnostic pop 23 | 24 | public slots: 25 | void HandleError(const QString& error); 26 | void HandleHeadStatus(wgc0310::HeadStatus headStatus); 27 | 28 | private: 29 | wgc0310::HeadStatus *m_HeadStatus; 30 | QThread *m_WorkerThread; 31 | }; 32 | 33 | struct OSFTrackParameter2 { 34 | std::size_t smoothSteps; 35 | float xRotationFix; 36 | float yRotationFix; 37 | float zRotationFix; 38 | 39 | float eyeMin = -1.0f; 40 | float eyeMax = 0.3f; 41 | }; 42 | 43 | class OSFTrackControl final : public QWidget { 44 | Q_OBJECT 45 | 46 | public: 47 | OSFTrackControl(wgc0310::HeadStatus *headStatus, 48 | QThread *workerThread, 49 | QWidget *parent = nullptr); 50 | ~OSFTrackControl() noexcept final; 51 | 52 | signals: 53 | #pragma clang diagnostic push 54 | #pragma ide diagnostic ignored "NotImplementedFunctions" 55 | void StartTracking(quint16 port); 56 | void StopTracking(); 57 | void SetParameters(OSFTrackParameter2 parameter); 58 | #pragma clang diagnostic pop 59 | 60 | public slots: 61 | void HandleError(const QString& error); 62 | void HandleHeadStatus(wgc0310::HeadStatus headStatus); 63 | 64 | private: 65 | wgc0310::HeadStatus *m_HeadStatus; 66 | QThread *m_WorkerThread; 67 | }; 68 | 69 | class MPTrackControl final : public QWidget { 70 | Q_OBJECT 71 | 72 | public: 73 | 74 | public slots: 75 | void HandleError(const QString& error); 76 | void HandleHeadStatus(wgc0310::HeadStatus headStatus); 77 | 78 | private: 79 | wgc0310::HeadStatus *m_HeadStatus; 80 | wgc0310::BodyStatus *m_BodyStatus; 81 | QThread *m_WorkerThread; 82 | }; 83 | 84 | class ManualTrackControl : public QWidget { 85 | Q_OBJECT 86 | 87 | public: 88 | ManualTrackControl(wgc0310::HeadStatus *headStatus, 89 | wgc0310::ScreenDisplayMode *screenDisplayMode, 90 | QWidget *parent = nullptr); 91 | 92 | private: 93 | wgc0310::HeadStatus *m_HeadStatus; 94 | wgc0310::ScreenDisplayMode *m_ScreenDisplayMode; 95 | }; 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/util/Constants.cc: -------------------------------------------------------------------------------- 1 | namespace cw { 2 | } // namespace cw 3 | -------------------------------------------------------------------------------- /src/util/DynLoad.cc: -------------------------------------------------------------------------------- 1 | #include "util/DynLoad.h" 2 | 3 | #include 4 | #include 5 | 6 | #ifdef CW_WIN32 7 | #include 8 | #endif // CW_WIN32 9 | 10 | namespace cw { 11 | 12 | #ifdef CW_WIN32 13 | 14 | void *LoadSharedObject(const QString& fileName) { 15 | QString escaped = fileName; 16 | escaped.replace("/", "\\", Qt::CaseInsensitive); 17 | HANDLE h = LoadLibraryW(escaped.toStdWString().c_str()); 18 | if (h == nullptr) { 19 | DWORD err = GetLastError(); 20 | qWarning() << "GetLastError() =" << err; 21 | } 22 | return h; 23 | } 24 | 25 | void* TryReadSymbolImpl(void *handle, const char *symbol) { 26 | return reinterpret_cast( 27 | GetProcAddress(reinterpret_cast(handle), symbol) 28 | ); 29 | } 30 | 31 | void DetachSharedObject(void *handle) { 32 | FreeLibrary(reinterpret_cast(handle)); 33 | } 34 | 35 | #else 36 | 37 | #include 38 | 39 | void *LoadSharedObject(const QString& fileName) { 40 | void *descriptor = dlopen(fileName.toStdString().c_str(), RTLD_LAZY); 41 | if (descriptor == nullptr) { 42 | qWarning() << "dlError() =" << dlerror(); 43 | } 44 | return descriptor; 45 | } 46 | 47 | void *TryReadSymbolImpl(void *handle, const char *symbol) { 48 | return reinterpret_cast(dlsym(handle, symbol)); 49 | } 50 | 51 | void DetachSharedObject(void *handle) { 52 | dlclose(handle); 53 | } 54 | 55 | #endif // CW_WIN32 56 | 57 | } // namespace cw 58 | -------------------------------------------------------------------------------- /src/util/FileUtil.cc: -------------------------------------------------------------------------------- 1 | #include "util/FileUtil.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace cw { 8 | 9 | bool IsFileExists(QString const& fileName) { 10 | return QFile::exists(fileName); 11 | } 12 | 13 | QString ReadToString(QString const& fileName) { 14 | QFile f(fileName); 15 | f.open(QIODevice::ReadOnly); 16 | if (!f.isOpen()) { 17 | qCritical() << "ReadToString(QString const&): cannot read from file" 18 | << fileName; 19 | return {}; 20 | } 21 | 22 | QTextStream textStream(&f); 23 | return textStream.readAll(); 24 | } 25 | 26 | bool WriteToFile(const QString &fileName, const QString &content) { 27 | QFile f(fileName); 28 | f.open(QIODevice::WriteOnly); 29 | 30 | QTextStream textStream(&f); 31 | textStream << content; 32 | 33 | return f.error() == QFileDevice::NoError; 34 | } 35 | 36 | } // namespace cw 37 | -------------------------------------------------------------------------------- /src/wgc0310/BodyAnim.cc: -------------------------------------------------------------------------------- 1 | #include "wgc0310/BodyAnim.h" 2 | #include "wgc0310/BodyStatus.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace wgc0310 { 9 | 10 | AnimationSection::AnimationSection() noexcept 11 | : totalFrameCount(0) 12 | {} 13 | 14 | void AnimationSection::AddCommand(AnimationCommand command) noexcept { 15 | totalFrameCount = std::max(totalFrameCount, command.frameCount); 16 | commandList.push_back(command); 17 | } 18 | 19 | void AnimationSection::ApplyAnimationFrame(BodyStatus *bodyStatus, 20 | std::size_t frame) const noexcept { 21 | for (const auto &command : commandList) { 22 | if (frame >= command.frameCount) { 23 | continue; 24 | } 25 | 26 | ArmStatus &arm = command.isLeft ? bodyStatus->leftArmStatus 27 | : bodyStatus->rightArmStatus; 28 | arm.rotation[command.rotationAxisIndex] += command.frameRotation; 29 | } 30 | } 31 | 32 | #define PARSE_DOUBLE(v, s, r) \ 33 | double v = (s).toDouble(&(r)); \ 34 | if (!(r)) { \ 35 | qWarning() << "error processing file:" \ 36 | << fileName \ 37 | << "line:" \ 38 | << lineNo \ 39 | << "(invalid float value)"; \ 40 | continue; \ 41 | } 42 | 43 | #define PARSE_UINT(v, s, r) \ 44 | std::size_t v = (s).toUInt(&(r)); \ 45 | if (!(r)) { \ 46 | qWarning() << "error processing file:" \ 47 | << fileName \ 48 | << "line:" \ 49 | << lineNo \ 50 | << "(invalid int value)"; \ 51 | continue; \ 52 | } 53 | 54 | std::unique_ptr LoadBodyAnimation(const char *fileName) { 55 | QFile file(fileName); 56 | if (!file.open(QIODevice::ReadOnly)) { 57 | qWarning() << "cannot open animation file:" << fileName; 58 | return nullptr; 59 | } 60 | 61 | QTextStream textStream(&file); 62 | std::unique_ptr animation = std::make_unique(); 63 | 64 | std::size_t lineNo = 0; 65 | while (!textStream.atEnd()) { 66 | QString line = textStream.readLine().trimmed(); 67 | lineNo += 1; 68 | 69 | if (line.isEmpty() || line.startsWith('#')) { 70 | continue; 71 | } 72 | 73 | if (line.startsWith("n=")) { 74 | animation->SetAnimationName(line.replace("n=", "").trimmed()); 75 | continue; 76 | } 77 | 78 | if (line == "s") { 79 | animation->AddSection(); 80 | continue; 81 | } 82 | 83 | QStringList parts = line.split(' '); 84 | if (parts.length() == 4 && (parts[0] == "l" || parts[0] == "r")) { 85 | bool isLeft = parts[0] == "l"; 86 | bool success; 87 | PARSE_UINT(axisIndex, parts[1], success) 88 | PARSE_DOUBLE(rotation, parts[2], success) 89 | PARSE_UINT(frameCount, parts[3], success) 90 | 91 | animation->AddCommand(fileName, lineNo, AnimationCommand { 92 | .isLeft = isLeft, 93 | .rotationAxisIndex = axisIndex, 94 | .frameRotation = 95 | static_cast(rotation / static_cast(frameCount)), 96 | .frameCount = frameCount 97 | }); 98 | } else { 99 | qWarning() << "error loading animation:" 100 | << fileName 101 | << "line:" 102 | << lineNo 103 | << "(command not understood)"; 104 | } 105 | } 106 | 107 | return animation; 108 | } 109 | 110 | #undef PARSE_DOUBLE 111 | #undef PARSE_INT 112 | 113 | void BodyAnimation::AddSection() noexcept { 114 | m_Sections.emplace_back(); 115 | } 116 | 117 | void BodyAnimation::AddCommand( 118 | const char *fileName, 119 | std::size_t lineNo, 120 | AnimationCommand command 121 | ) noexcept { 122 | if (m_Sections.empty()) { 123 | qWarning() << "error loading animation:" 124 | << fileName 125 | << "line:" 126 | << lineNo 127 | << "(cannot define rotation without section)"; 128 | return; 129 | } 130 | 131 | m_Sections.back().AddCommand(command); 132 | } 133 | 134 | } // namespace wgc0310 135 | -------------------------------------------------------------------------------- /src/wgc0310/BodyStatus.cc: -------------------------------------------------------------------------------- 1 | #include "wgc0310/BodyStatus.h" 2 | 3 | namespace wgc0310 { 4 | 5 | PlayAnimationStatus::PlayAnimationStatus() noexcept 6 | : m_Animation(nullptr), 7 | m_CurrentSection(0), 8 | m_CurrentFrameCount(0) 9 | {} 10 | 11 | void 12 | PlayAnimationStatus::SetAnimation(BodyAnimation const* animation) noexcept { 13 | m_Animation = animation; 14 | m_CurrentSection = 0; 15 | m_CurrentFrameCount = 0; 16 | } 17 | 18 | bool PlayAnimationStatus::NextTick(BodyStatus *bodyStatus) noexcept { 19 | if (!m_Animation) { 20 | return false; 21 | } 22 | 23 | std::vector const& sections = m_Animation->GetSections(); 24 | 25 | restart: 26 | if (m_CurrentSection >= sections.size()) { 27 | return false; 28 | } 29 | 30 | AnimationSection const& section = sections[m_CurrentSection]; 31 | if (m_CurrentFrameCount >= section.totalFrameCount) { 32 | m_CurrentSection += 1; 33 | m_CurrentFrameCount = 0; 34 | goto restart; 35 | } 36 | 37 | section.ApplyAnimationFrame(bodyStatus, m_CurrentFrameCount); 38 | m_CurrentFrameCount += 1; 39 | return true; 40 | } 41 | 42 | } // namespace wgc0310 43 | -------------------------------------------------------------------------------- /src/wgc0310/Mesh.cc: -------------------------------------------------------------------------------- 1 | #include "wgc0310/Mesh.h" 2 | 3 | #include "GlobalConfig.h" 4 | #include "cwglx/GL/GLImpl.h" 5 | #include "cwglx/Base/Shader.h" 6 | #include "cwglx/Object/WavefrontLoader.h" 7 | #include "util/FileUtil.h" 8 | 9 | namespace wgc0310 { 10 | 11 | static cw::GLObject 12 | LoadObjectEx(cw::GLObjectContext *ctx, GLFunctions *f, QString const& objectFile) { 13 | QString patchPath = QStringLiteral("./patch/model/%1").arg(objectFile); 14 | if (cw::IsFileExists(patchPath)) { 15 | return cw::LoadObject( 16 | ctx, 17 | f, 18 | "./patch/model", 19 | objectFile, 20 | cw::GlobalConfig::Instance.linearSampling, 21 | cw::GlobalConfig::Instance.anisotropyFilter 22 | ); 23 | } 24 | return cw::LoadObject( 25 | ctx, 26 | f, 27 | ":/model", 28 | objectFile, 29 | cw::GlobalConfig::Instance.linearSampling, 30 | cw::GlobalConfig::Instance.anisotropyFilter 31 | ); 32 | } 33 | 34 | WGCModel LoadWGCModel(cw::GLObjectContext *ctx, GLFunctions *f) { 35 | return { 36 | .testObject = LoadObjectEx(ctx, f, "TestObject.obj") 37 | }; 38 | } 39 | 40 | void WGCModel::Delete(GLFunctions *f) { 41 | testObject.Delete(f); 42 | } 43 | 44 | } // namespace wgc0310 45 | -------------------------------------------------------------------------------- /src/wgc0310/ScreenAnimationStatus.cc: -------------------------------------------------------------------------------- 1 | #include "include/wgc0310/ScreenAnimationStatus.h" 2 | 3 | #include 4 | #include 5 | #include "cwglx/GL/GLImpl.h" 6 | #include "cwglx/Base/Texture.h" 7 | 8 | namespace wgc0310 { 9 | 10 | ScreenAnimationStatus::ScreenAnimationStatus() 11 | : staticScreen(nullptr), 12 | animation(nullptr), 13 | m_NeedRewind(false) 14 | {} 15 | 16 | void ScreenAnimationStatus::PlayStaticAnimation(StaticScreenImage *staticScreen) { 17 | Reset(); 18 | this->staticScreen = staticScreen; 19 | } 20 | 21 | void ScreenAnimationStatus::PlayAnimation(WGAPIAnimation *animation) { 22 | Reset(); 23 | 24 | this->animation = animation; 25 | m_NeedRewind = true; 26 | } 27 | 28 | bool ScreenAnimationStatus::HasThingToDraw() const noexcept { 29 | return animation || staticScreen; 30 | } 31 | 32 | void ScreenAnimationStatus::DrawOnScreen(GLFunctions *f) const noexcept { 33 | if (staticScreen) { 34 | } else if (animation) { 35 | if (m_NeedRewind) { 36 | m_NeedRewind = false; 37 | animation->Rewind(); 38 | } 39 | 40 | animation->Draw(f); 41 | } 42 | } 43 | 44 | void ScreenAnimationStatus::Reset() { 45 | if (animation) { 46 | QWidget *controlWidget = animation->GetControlWidget(); 47 | if (controlWidget) { 48 | controlWidget->close(); 49 | } 50 | } 51 | 52 | staticScreen = nullptr; 53 | animation = nullptr; 54 | } 55 | 56 | void ScreenAnimationStatus::NextTick() { 57 | if (animation) { 58 | animation->NextTick(); 59 | } 60 | } 61 | 62 | } // namespace wgc0310 63 | -------------------------------------------------------------------------------- /src/wgc0310/ScreenCurveHelper.cc: -------------------------------------------------------------------------------- 1 | #include "include/wgc0310/ScreenCurveHelper.h" 2 | 3 | #include 4 | #include 5 | #include "util/Constants.h" 6 | 7 | namespace wgc0310 { 8 | 9 | /// computes the X-Z mapping of vertical cylinder 10 | static std::vector> 11 | ComputeVCylinder(double surfaceWidth, 12 | double bulb, 13 | std::size_t segments) { 14 | double radius = (bulb / 2) + (surfaceWidth * surfaceWidth / (8 * bulb)); 15 | double base = radius - bulb; 16 | double startAngleRad = std::asin(surfaceWidth / (2 * radius)); 17 | double startAngle = -cw::RadToDeg(startAngleRad); 18 | double endAngle = -startAngle; 19 | 20 | double angleStep = (endAngle - startAngle) / static_cast(segments); 21 | 22 | std::vector> result; 23 | result.reserve(segments + 1); 24 | for (std::size_t i = 0; i <= segments; i++) { 25 | double angle = startAngle + static_cast(i) * angleStep; 26 | double x = std::sin(cw::DegToRad(angle)) * radius; 27 | double z = std::cos(cw::DegToRad(angle)) * radius - base; 28 | 29 | result.emplace_back(x, z); 30 | } 31 | 32 | return result; 33 | } 34 | 35 | /// computes the Y-Z mapping of horizontal cylinder 36 | static std::vector> 37 | ComputeHCylinder(double surfaceHeight, 38 | double bulb, 39 | std::size_t segments) { 40 | // actually there's no implementation difference between vSegments and 41 | // hSegments, just forward to the vSegments version 42 | 43 | return ComputeVCylinder(surfaceHeight, bulb, segments); 44 | } 45 | 46 | std::vector> 47 | ComputeScreenVertices(double screenWidth, 48 | double screenHeight, 49 | double bulb, 50 | std::size_t hSegments, 51 | std::size_t vSegments) { 52 | Q_ASSERT(hSegments % 2 == 0 53 | && vSegments % 2 == 0 54 | && "non-even segments could be inaccurate and is thus prohibited"); 55 | 56 | std::vector> vCylinder = 57 | ComputeVCylinder(screenWidth, bulb / 2.0, hSegments); 58 | std::vector> hCylinder = 59 | ComputeHCylinder(screenHeight, bulb / 2.0, vSegments); 60 | 61 | // compute the vertices 62 | std::vector> result; 63 | result.reserve(vSegments + 1); 64 | 65 | for (std::size_t i = 0; i <= vSegments; i++) { 66 | const auto& [y, z1] = hCylinder[vSegments - i]; 67 | 68 | std::vector line; 69 | line.reserve(hSegments + 1); 70 | 71 | for (std::size_t j = 0; j <= hSegments; j++) { 72 | const auto& [x, z2] = vCylinder[j]; 73 | 74 | line.emplace_back(x, y, z1 + z2); 75 | } 76 | 77 | result.push_back(std::move(line)); 78 | } 79 | 80 | return result; 81 | } 82 | 83 | } // namespace wgc0310 84 | -------------------------------------------------------------------------------- /src/wgc0310/ScreenGlass.cc: -------------------------------------------------------------------------------- 1 | #include "include/wgc0310/ScreenGlass.h" 2 | #include "include/wgc0310/ScreenCurveHelper.h" 3 | 4 | namespace wgc0310 { 5 | 6 | std::unique_ptr ScreenGlass() { 7 | std::vector> vertices = 8 | ComputeScreenVertices(25.0, 18.75, 1.25, 160, 120); 9 | auto plainMesh = std::make_unique(); 10 | 11 | for (std::size_t x = 0; x < 160; x++) { 12 | for (std::size_t y = 0; y < 120; y++) { 13 | cw::Vertex pointA = vertices[y][x]; 14 | cw::Vertex pointB = vertices[y + 1][x]; 15 | cw::Vertex pointC = vertices[y + 1][x + 1]; 16 | cw::Vertex pointD = vertices[y][x + 1]; 17 | 18 | plainMesh->AddTriangle(cw::Triangle {pointA, pointB, pointC }); 19 | plainMesh->AddTriangle(cw::Triangle {pointA, pointC, pointD }); 20 | } 21 | } 22 | 23 | return plainMesh; 24 | } 25 | 26 | } // namespace wgc0310 27 | --------------------------------------------------------------------------------