├── demo-Lines.exe ├── demo-Teapot.exe ├── ege ├── lib │ ├── mingw64 │ │ ├── MinGW-w64 GCC 8.1.0.txt │ │ └── mingw-w64-gcc-8.1.0-x86_64 │ │ │ └── libgraphics.a │ ├── macOS │ │ └── libgraphics.a │ ├── vs2010 │ │ ├── graphics.lib │ │ └── amd64 │ │ │ └── graphics.lib │ ├── vs2015 │ │ ├── graphics.lib │ │ ├── amd64 │ │ │ └── graphics.lib │ │ └── VS2015 Update3.txt │ ├── vs2017 │ │ ├── x64 │ │ │ └── graphics.lib │ │ ├── x86 │ │ │ └── graphics.lib │ │ └── VS2017 Community 15.9.63.txt │ ├── vs2019 │ │ ├── x64 │ │ │ └── graphics.lib │ │ └── x86 │ │ │ └── graphics.lib │ ├── vs2022 │ │ ├── x64 │ │ │ └── graphics.lib │ │ └── x86 │ │ │ └── graphics.lib │ └── mingw-w64-debian │ │ └── libgraphics.a └── include │ ├── graphics.h │ ├── ege │ ├── fps.h │ ├── label.h │ ├── sys_edit.h │ ├── egecontrolbase.h │ └── button.h │ └── ege.h ├── screenshot0.jpg ├── screenshot1.jpg ├── screenshot2.jpg ├── demo-SceneRoaming.exe ├── README.md ├── .vscode ├── settings.json ├── launch.json ├── c_cpp_properties.json └── tasks.json ├── algorithm ├── cgeStaticAssert.h ├── cgeScene.h ├── cgeVec.h └── cgeMat.h ├── LICENSE.txt ├── model └── cgeModelCube.h ├── .gitattributes ├── .gitignore ├── CMakeLists.txt ├── demo-Lines.cpp ├── demo-Teapot.cpp └── demo-SceneRoaming.cpp /demo-Lines.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/demo-Lines.exe -------------------------------------------------------------------------------- /demo-Teapot.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/demo-Teapot.exe -------------------------------------------------------------------------------- /ege/lib/mingw64/MinGW-w64 GCC 8.1.0.txt: -------------------------------------------------------------------------------- 1 | https://sourceforge.net/projects/mingw-w64/ -------------------------------------------------------------------------------- /screenshot0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/screenshot0.jpg -------------------------------------------------------------------------------- /screenshot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/screenshot1.jpg -------------------------------------------------------------------------------- /screenshot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/screenshot2.jpg -------------------------------------------------------------------------------- /demo-SceneRoaming.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/x-ege/ege-soft-3d/HEAD/demo-SceneRoaming.exe -------------------------------------------------------------------------------- /ege/lib/macOS/libgraphics.a: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:46fe3d66b57b0cc1d83bb676f6ae7f6198e60dbf3cb54fcc9c9337f7a880c3fc 3 | size 916094 4 | -------------------------------------------------------------------------------- /ege/lib/vs2010/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1509627a80868a70046a5f73c13ba5504146910973535d5c770b77199b20c01b 3 | size 1714276 4 | -------------------------------------------------------------------------------- /ege/lib/vs2015/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:da215883c1d0c9c10e4418f647811b4612d12a1deb27e1ab7a2e9a9fe8940248 3 | size 1015200 4 | -------------------------------------------------------------------------------- /ege/lib/vs2010/amd64/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:92f39bcb5f92e00ac2c46d005bcee62d8b130a605799a2aa03307dc2f9cb7465 3 | size 2550518 4 | -------------------------------------------------------------------------------- /ege/lib/vs2015/amd64/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d64e6408de092363e606f39921132f5440e6278ae6ba673cc55b7379156ed2f0 3 | size 1689066 4 | -------------------------------------------------------------------------------- /ege/lib/vs2017/x64/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4a14ee6a1e32cbb8a2cc382ce85d649a2f10233c552c8cfe33b6c7d98c67821e 3 | size 1741458 4 | -------------------------------------------------------------------------------- /ege/lib/vs2017/x86/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f6e491c62c518d54ce122e7fe0c19d395ccd2d3ddec264d158bbcbb445d11035 3 | size 1045882 4 | -------------------------------------------------------------------------------- /ege/lib/vs2019/x64/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d77ac7d11def0b6ba8f3cea3f6c90578acc766a8b9be7817952b1d6a3f96d2ac 3 | size 1802780 4 | -------------------------------------------------------------------------------- /ege/lib/vs2019/x86/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4ae5473decf783191f7a1f7c59b80e41eb55cb69d7218a1afb90b9bfeb194216 3 | size 1089144 4 | -------------------------------------------------------------------------------- /ege/lib/vs2022/x64/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:52be26d398d2f4dbde7c41a8ea0b8efaa6bf5a2bd47be784ff856f521ae9fcc6 3 | size 1828398 4 | -------------------------------------------------------------------------------- /ege/lib/vs2022/x86/graphics.lib: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:409b9ec8547ec18e28974f711b6cefd86b6f55c4490cb54b8cf44ba52ac88fed 3 | size 1095734 4 | -------------------------------------------------------------------------------- /ege/lib/mingw-w64-debian/libgraphics.a: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:75f402bbf846628ecef583d27cbfd6b36e18bcfb5a3fc337a1258f6e0ba9968b 3 | size 912662 4 | -------------------------------------------------------------------------------- /ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64/libgraphics.a: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:db424357d4a97db951071d330265672b4085418498e350a9548f426e02c5cb71 3 | size 897872 4 | -------------------------------------------------------------------------------- /ege/lib/vs2017/VS2017 Community 15.9.63.txt: -------------------------------------------------------------------------------- 1 | https://download.visualstudio.microsoft.com/download/pr/57c99182-2828-4fc1-8b36-271e2472c838/91d7b8d8ba556b1e8723ca67a0f1e2e4a8274f7dfccbeae567e78b22f0db3f6d/vs_Community.exe -------------------------------------------------------------------------------- /ege/lib/vs2015/VS2015 Update3.txt: -------------------------------------------------------------------------------- 1 | Visual Studio Community 2015 with Update 3 (x86 and x64) - DVD (Chinese-Simplified) 2 | http://download.microsoft.com/download/5/d/1/5d1ec81e-bc59-448f-9ab6-27636d5cc18a/vs2015.3.com_chs.iso 3 | 4 | 5 | Visual Studio Community 2015 with Update 3 (x86 and x64) - DVD (English) 6 | http://download.microsoft.com/download/b/e/d/bedddfc4-55f4-4748-90a8-ffe38a40e89f/vs2015.3.com_enu.iso -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

SIMPLE SOFT 3D

2 | 3 |

本项目主要使用C++完成了OpenGL大部分矩阵和向量操作,为这方面的计算提供便利。同时附带两个小demo以供展示。矩阵向量算法部分代码应该可以兼容各个支持C++的编译器(iOS下可以mm文件后缀方式混用以及安卓下使用NDK编译)。

4 | 5 |

部分代码来参考自OpenGL.org(部分矩阵运算代码),文件中有标注

6 | 7 |

LICENSE 请参照The MIT License

8 |

ScreenShot1

9 |

10 | 11 |

ScreenShot2

12 |

13 | 14 |

ScreenShot3

15 |

16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", 3 | "C_Cpp.errorSquiggles": "disabled", 4 | "cmake.configureArgs": [ 5 | "-DCMAKE_SYSTEM_NAME=Windows", 6 | "-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc", 7 | "-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++", 8 | "-DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres", 9 | "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER", 10 | "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY", 11 | "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY", 12 | "-DPKG_CONFIG_EXECUTABLE=x86_64-w64-mingw32-pkg-config", 13 | ], 14 | "C_Cpp.default.compilerPath": "x86_64-w64-mingw32-g++" 15 | } -------------------------------------------------------------------------------- /ege/include/graphics.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * EGE (Easy Graphics Engine) 24.04 3 | * FileName: graphics.h 4 | * Website: https://xege.org 5 | * Community: https://club.xege.org 6 | * GitHub: https://github.com/wysaid/xege 7 | * GitHub: https://github.com/Easy-Graphics-Engine 8 | * Gitee: https://gitee.com/xege/xege 9 | * Blog: https://wysaid.org 10 | * E-Mail: this@wysaid.org 11 | * E-Mail: misakamm@gmail.com 12 | * 13 | *********************************************************/ 14 | 15 | #ifndef EGE_GRAPHICS_H 16 | #define EGE_GRAPHICS_H 17 | 18 | #ifndef __cplusplus 19 | #error You must use a C++ compiler and ensure that your source files is named with the '.cpp' suffix. 20 | #endif 21 | 22 | #include "ege.h" 23 | using namespace ege; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /algorithm/cgeStaticAssert.h: -------------------------------------------------------------------------------- 1 | /* 2 | @Author: wysaid 3 | @Blog: blog.wysaid.org 4 | @Date: 2013-10-31 5 | */ 6 | 7 | #ifndef _CGE_STATICASSERT_H_ 8 | #define _CGE_STATICASSERT_H_ 9 | 10 | #ifndef _CGE_STATIC_ASSERT_ 11 | 12 | #define cgeStaticAssert(value) static_assert(value, "Invalid Parameters!") 13 | 14 | #else 15 | 16 | #if defined(DEBUG) || defined(_DEBUG) 17 | 18 | template 19 | struct _CGEStaticAssert ; 20 | 21 | template<> 22 | struct _CGEStaticAssert { int dummy; }; 23 | 24 | template 25 | struct __CGEStaticAssert {}; 26 | 27 | #define cgeStaticAssert(value) do \ 28 | {\ 29 | typedef __CGEStaticAssert<\ 30 | sizeof(_CGEStaticAssert<(bool)(value)>)\ 31 | > ___CGEStaticAssert;\ 32 | } while (0) 33 | 34 | #else 35 | 36 | #define cgeStaticAssert(...) 37 | 38 | #endif 39 | 40 | #endif 41 | 42 | #endif //_CGE_STATICASSERT_H_ 43 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 wysaid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /ege/include/ege/fps.h: -------------------------------------------------------------------------------- 1 | #ifndef EGE_FPS_H 2 | #define EGE_FPS_H 3 | 4 | #include "egecontrolbase.h" 5 | 6 | namespace ege 7 | { 8 | 9 | class fps : public egeControlBase 10 | { 11 | public: 12 | CTL_PREINIT(fps, egeControlBase) 13 | { 14 | // do sth. before sub objects' construct function call 15 | } 16 | 17 | CTL_PREINITEND; 18 | 19 | fps(CTL_DEFPARAM) : CTL_INITBASE(egeControlBase) 20 | { 21 | CTL_INIT; // must be the first line 22 | directdraw(true); 23 | enable(false); 24 | } 25 | 26 | void onDraw(PIMAGE pimg) const 27 | { 28 | char str[16] = "fps ", *pstr = str; 29 | double fps = getfps() + 0.005; 30 | int a = (int)fps, b = (int)((fps - a) * 100); 31 | 32 | while (*pstr) { 33 | ++pstr; 34 | } 35 | 36 | pstr[-1] = (char)(b % 10 + '0'); 37 | pstr[-2] = (char)(b / 10 + '0'); 38 | pstr[-3] = '.'; 39 | pstr -= 4; 40 | 41 | for (; a > 0; --pstr) { 42 | pstr[0] = a % 10 + '0'; 43 | a /= 10; 44 | } 45 | 46 | setcolor(WHITE, pimg); 47 | setfillcolor(BLACK, pimg); 48 | setbkmode(OPAQUE, pimg); 49 | setfont(12, 0, "SimSun", pimg); 50 | outtextxy(0, 0, str, pimg); 51 | } 52 | }; 53 | 54 | } // namespace ege 55 | #endif /*EGE_FPS_H*/ 56 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Debug", 9 | "type": "cppvsdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/Debug/ege-demo.exe", 12 | "stopAtEntry": false, 13 | "cwd": "${workspaceFolder}/build", 14 | "environment": [], 15 | "console": "integratedTerminal", 16 | "preLaunchTask": "Run Project (Debug)", 17 | 18 | "osx": { 19 | "program": "/bin/bash", 20 | "args": [ 21 | "-c", 22 | "echo Run ${workspaceFolder}/build/ege-demo.exe done." 23 | ], 24 | }, 25 | "windows": { 26 | "preLaunchTask": "Build Project (Debug)" 27 | }, 28 | }, 29 | { 30 | "name": "Launch Release", 31 | "type": "cppvsdbg", 32 | "request": "launch", 33 | "program": "${workspaceFolder}/build/Release/ege-demo.exe", 34 | "stopAtEntry": false, 35 | "cwd": "${workspaceFolder}/build", 36 | "environment": [], 37 | "console": "integratedTerminal", 38 | "preLaunchTask": "Run Project (Release)", 39 | 40 | "osx": { 41 | "program": "/bin/bash", 42 | "args": [ 43 | "-c", 44 | "echo Run ${workspaceFolder}/build/ege-demo.exe done." 45 | ], 46 | }, 47 | "windows": { 48 | "preLaunchTask": "Build Project (Release)" 49 | }, 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "env": { 4 | "systemIncludePath": [ 5 | "${workspaceFolder}/ege", 6 | "${workspaceFolder}/ege/include" 7 | ] 8 | }, 9 | "configurations": [ 10 | { 11 | "name": "Mac", 12 | "cStandard": "c11", 13 | "cppStandard": "c++17", 14 | "defines": [ 15 | "_FORTIFY_SOURCE=0", 16 | "SHOW_CONSOLE=1" 17 | ], 18 | "compilerArgs": [ 19 | "-mwindows", 20 | "-static", 21 | "-static-libgcc", 22 | "-static-libstdc++" 23 | ], 24 | "includePath": [ 25 | "${myDefaultIncludePath}" 26 | ], 27 | "configurationProvider": "ms-vscode.cmake-tools" 28 | }, 29 | { 30 | "name": "Linux", 31 | "cStandard": "c11", 32 | "cppStandard": "c++17", 33 | "compilerPath": "x86_64-w64-mingw32-g++", 34 | "defines": [ 35 | "_FORTIFY_SOURCE=0", 36 | "SHOW_CONSOLE=1" 37 | ], 38 | "compilerArgs": [ 39 | "-mwindows", 40 | "-static", 41 | "-static-libgcc", 42 | "-static-libstdc++" 43 | ], 44 | "includePath": [ 45 | "${myDefaultIncludePath}" 46 | ], 47 | "configurationProvider": "ms-vscode.cmake-tools" 48 | }, 49 | { 50 | "name": "Win32", 51 | "cStandard": "c11", 52 | "cppStandard": "c++17", 53 | "compilerPath": "${default}", 54 | "includePath": [ 55 | "${myDefaultIncludePath}", 56 | "SHOW_CONSOLE=1" 57 | ], 58 | "configurationProvider": "ms-vscode.cmake-tools" 59 | } 60 | ], 61 | "enableConfigurationSquiggles": false 62 | } -------------------------------------------------------------------------------- /model/cgeModelCube.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cgeModelCube.h 3 | * 4 | * Created on: 2014-10-30 5 | * Author: Wang Yang 6 | * Mail: admin@wysaid.org 7 | */ 8 | 9 | #ifndef _CGEMODELCUBE_H_ 10 | #define _CGEMODELCUBE_H_ 11 | 12 | namespace CGE 13 | { 14 | //使用 GL_TRIANGLES 方式绘制 15 | struct ModelCube 16 | { 17 | static const float vertices[]; 18 | static const int vertDataSize = 3; // 每个顶点包含三个分量 19 | static const int vertSize; 20 | 21 | static const float vertTexture[]; // 纹理顶点 22 | static const int vertTextureSize; //每个纹理顶点包含两个分量 23 | 24 | static const float vertNormals[]; //顶点法向量 25 | 26 | static const unsigned short vertIndexes[]; 27 | static const int vertIndexSize; 28 | 29 | }; 30 | 31 | const float ModelCube::vertices[] = { 32 | 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, 33 | 1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 34 | 1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, 35 | -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, 36 | -1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, 37 | 1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 38 | }; 39 | 40 | const unsigned short ModelCube::vertIndexes[] = { 41 | 0, 1, 2, 0, 2, 3, 42 | 4, 5, 6, 4, 6, 7, 43 | 8, 9,10, 8,10,11, 44 | 12,13,14, 12,14,15, 45 | 16,17,18, 16,18,19, 46 | 20,21,22, 20,22,23 47 | }; 48 | 49 | const float ModelCube::vertTexture[] = { 50 | 1, 1, 0, 1, 0, 0, 1, 0, 51 | 0, 1, 0, 0, 1, 0, 1, 1, 52 | 1, 0, 1, 1, 0, 1, 0, 0, 53 | 1, 1, 0, 1, 0, 0, 1, 0, 54 | 0, 0, 1, 0, 1, 1, 0, 1, 55 | 0, 0, 1, 0, 1, 1, 0, 1 56 | }; 57 | 58 | const float ModelCube::vertNormals[] = { 59 | 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 60 | 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 61 | 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 62 | -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 63 | 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 64 | 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 65 | }; 66 | 67 | const int ModelCube::vertSize = sizeof(ModelCube::vertices); 68 | const int ModelCube::vertTextureSize = sizeof(ModelCube::vertTexture); 69 | const int ModelCube::vertIndexSize = sizeof(ModelCube::vertIndexes); 70 | } 71 | 72 | #endif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | # Custom for Visual Studio 4 | *.cs diff=csharp 5 | *.sln merge=union 6 | *.csproj merge=union 7 | *.vbproj merge=union 8 | *.fsproj merge=union 9 | *.dbproj merge=union 10 | # Standard to msysgit 11 | *.doc diff=astextplain 12 | *.DOC diff=astextplain 13 | *.docx diff=astextplain 14 | *.DOCX diff=astextplain 15 | *.dot diff=astextplain 16 | *.DOT diff=astextplain 17 | *.pdf diff=astextplain 18 | *.PDF diff=astextplain 19 | *.rtf diff=astextplain 20 | *.RTF diff=astextplain 21 | ege/lib/vs2015/graphics.lib filter=lfs diff=lfs merge=lfs -text 22 | ege/lib/vs2022/x64/graphics.lib filter=lfs diff=lfs merge=lfs -text 23 | ege/lib/vs2022/x86/graphics.lib filter=lfs diff=lfs merge=lfs -text 24 | ege/lib/vc6/graphics.lib filter=lfs diff=lfs merge=lfs -text 25 | ege/lib/vs2010/graphics.lib filter=lfs diff=lfs merge=lfs -text 26 | ege/lib/vs2015/amd64/graphics.lib filter=lfs diff=lfs merge=lfs -text 27 | ege/lib/vs2017/x64/graphics.lib filter=lfs diff=lfs merge=lfs -text 28 | ege/lib/vs2017/x86/graphics.lib filter=lfs diff=lfs merge=lfs -text 29 | ege/lib/vs2019/x64/graphics.lib filter=lfs diff=lfs merge=lfs -text 30 | ege/lib/vs2019/x86/graphics.lib filter=lfs diff=lfs merge=lfs -text 31 | ege/lib/vs2010/amd64/graphics.lib filter=lfs diff=lfs merge=lfs -text 32 | ege/lib/devcpp/libgraphics.a filter=lfs diff=lfs merge=lfs -text 33 | ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64-posix-seh/libgraphics.a filter=lfs diff=lfs merge=lfs -text 34 | ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64-win32-seh/libgraphics.a filter=lfs diff=lfs merge=lfs -text 35 | ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64-win32-sjlj/libgraphics.a filter=lfs diff=lfs merge=lfs -text 36 | ege/lib/mingw-w64-debian/libgraphics.a filter=lfs diff=lfs merge=lfs -text 37 | ege/lib/codeblocks/libgraphics.a filter=lfs diff=lfs merge=lfs -text 38 | ege/lib/devcpp/32/libgraphics.a filter=lfs diff=lfs merge=lfs -text 39 | ege/lib/macOS/libgraphics.a filter=lfs diff=lfs merge=lfs -text 40 | ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64-posix-sjlj/libgraphics.a filter=lfs diff=lfs merge=lfs -text 41 | ege/lib/redpanda/libgraphics.a filter=lfs diff=lfs merge=lfs -text 42 | ege/lib/mingw64/mingw-w64-gcc-8.1.0-x86_64/libgraphics.a filter=lfs diff=lfs merge=lfs -text 43 | -------------------------------------------------------------------------------- /ege/include/ege/label.h: -------------------------------------------------------------------------------- 1 | #ifndef EGE_LABEL_H 2 | #define EGE_LABEL_H 3 | 4 | #include "egecontrolbase.h" 5 | 6 | namespace ege 7 | { 8 | 9 | class label : public egeControlBase 10 | { 11 | public: 12 | CTL_PREINIT(label, egeControlBase) 13 | { 14 | // do sth. before sub objects' construct function call 15 | } 16 | 17 | CTL_PREINITEND; 18 | 19 | label(CTL_DEFPARAM) : CTL_INITBASE(egeControlBase) 20 | { 21 | CTL_INIT; // must be the first line 22 | size(64, 16); 23 | m_color = WHITE; 24 | m_bkcolor = BLACK; 25 | m_fontheight = 12; 26 | m_alpha = 0xff; 27 | m_transparent = false; 28 | strcpy(m_face, "SimSun"); 29 | redraw(); 30 | } 31 | 32 | void caption(const char* text) 33 | { 34 | strcpy(m_caption, text); 35 | redraw(); 36 | } 37 | 38 | const char* caption() const { return m_caption; } 39 | 40 | void fontsize(int height) 41 | { 42 | m_fontheight = height; 43 | redraw(); 44 | } 45 | 46 | int fontsize() const { return m_fontheight; } 47 | 48 | void font(const char* fontface) 49 | { 50 | strcpy(m_face, fontface); 51 | redraw(); 52 | } 53 | 54 | const char* font() const { return m_face; } 55 | 56 | void color(color_t color) 57 | { 58 | m_color = color; 59 | redraw(); 60 | } 61 | 62 | color_t color() const { return m_color; } 63 | 64 | void bkcolor(color_t color) 65 | { 66 | m_bkcolor = color; 67 | redraw(); 68 | } 69 | 70 | color_t bkcolor() const { return m_bkcolor; } 71 | 72 | void transparent(bool t) 73 | { 74 | m_transparent = t; 75 | redraw(); 76 | } 77 | 78 | bool transparent() const { return m_transparent; } 79 | 80 | void alpha(int alpha) 81 | { 82 | if (alpha < 0) { 83 | alpha = 0; 84 | } 85 | if (alpha > 0xff) { 86 | alpha = 0xff; 87 | } 88 | m_alpha = alpha; 89 | redraw(); 90 | } 91 | 92 | int alpha() const { return m_alpha; } 93 | 94 | void redraw() 95 | { 96 | PushTarget targer(buf()); 97 | 98 | if (m_alpha < 0xff || m_transparent) { 99 | blendmode(true); 100 | } else { 101 | blendmode(false); 102 | } 103 | 104 | setbkcolor_f(m_bkcolor); 105 | setcolor(m_color); 106 | cleardevice(); 107 | setbkmode(TRANSPARENT); 108 | setfont(m_fontheight, 0, m_face); 109 | outtextrect(0, 0, getw(), geth(), m_caption); 110 | 111 | if (m_transparent) { 112 | setbkcolor_f(BLACK, filter()); 113 | cleardevice(filter()); 114 | if (m_alpha < 0xff) { 115 | setcolor(EGERGB(m_alpha, m_alpha, m_alpha), filter()); 116 | } else { 117 | setcolor(0xFFFFFF, filter()); 118 | } 119 | setbkmode(TRANSPARENT, filter()); 120 | setfont(m_fontheight, 0, m_face, filter()); 121 | outtextrect(0, 0, getw(), geth(), m_caption, filter()); 122 | } else { 123 | if (m_alpha < 0xff) { 124 | setbkcolor_f(EGERGB(m_alpha, m_alpha, m_alpha), filter()); 125 | cleardevice(filter()); 126 | } 127 | } 128 | } 129 | 130 | protected: 131 | char m_caption[1024]; 132 | char m_face[32]; 133 | color_t m_color; 134 | color_t m_bkcolor; 135 | int m_alpha; 136 | bool m_transparent; 137 | int m_fontheight; 138 | }; 139 | 140 | } // namespace ege 141 | 142 | #endif /* EGE_LABEL_H */ 143 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | *.db 217 | *.opendb 218 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | if (CMAKE_HOST_UNIX) 4 | set(CMAKE_SYSTEM_NAME Windows) 5 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 6 | # cross compilers to use for C, C++ and RC 7 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 8 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) 9 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 10 | 11 | # modify default behavior of FIND_XXX() commands 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 13 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 14 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 15 | set(PKG_CONFIG_EXECUTABLE ${TOOLCHAIN_PREFIX}-pkg-config) 16 | endif () 17 | 18 | project(ege-demos LANGUAGES CXX) 19 | 20 | add_library(ege-common INTERFACE) 21 | target_include_directories(ege-common INTERFACE 22 | ${CMAKE_CURRENT_SOURCE_DIR}/ege/include 23 | ${CMAKE_CURRENT_SOURCE_DIR}/algorithm 24 | ${CMAKE_CURRENT_SOURCE_DIR}/model) 25 | 26 | # 设置静态库搜索路径 27 | 28 | if (MSVC) 29 | 30 | # 设置 MSVC 编译选项, 当版本大于 vs2019 时, 使用 c++17 标准. 31 | set(CPP_COMPILE_OPTIONS "/std:c++17") 32 | 33 | if (MSVC_VERSION GREATER_EQUAL 1930) 34 | # vs2022 以上, 静态库是兼容的. 35 | if (CMAKE_CL_64) 36 | set(osLibDir "vs2022/x64") 37 | else () 38 | set(osLibDir "vs2022/x86") 39 | endif () 40 | elseif (MSVC_VERSION GREATER_EQUAL 1920) 41 | # vs2019 以上, 静态库是兼容的. 42 | if (CMAKE_CL_64) 43 | set(osLibDir "vs2019/x64") 44 | else () 45 | set(osLibDir "vs2019/x86") 46 | endif () 47 | elseif (MSVC_VERSION GREATER_EQUAL 1910) 48 | # vs2017 49 | if (CMAKE_CL_64) 50 | set(osLibDir "vs2017/x64") 51 | else () 52 | set(osLibDir "vs2017/x86") 53 | endif () 54 | # 设置 MSVC 编译选项, 当版本为 vs2017 时, 使用 c++14 标准. 55 | set(CPP_COMPILE_OPTIONS "/std:c++14") 56 | elseif (MSVC_VERSION GREATER_EQUAL 1900) 57 | # vs2015 58 | if (CMAKE_CL_64) 59 | set(osLibDir "vs2015/amd64") 60 | else () 61 | set(osLibDir "vs2015") 62 | endif () 63 | # 设置 MSVC 编译选项, 当版本为 vs2015 时, 使用 c++14 标准. 64 | set (CPP_COMPILE_OPTIONS "/std:c++14") 65 | elseif(MSVC_VERSION GREATER_EQUAL 1600) 66 | 67 | if (MSVC_VERSION GREATER_EQUAL 1700) 68 | message(WARNING "You are using vs2012/vs2013, which is not tested, please use vs2010, vs2015 or later version of MSVC compiler.") 69 | endif() 70 | 71 | # vs2010 72 | if (CMAKE_CL_64) 73 | set(osLibDir "vs2010/amd64") 74 | else () 75 | set(osLibDir "vs2010") 76 | endif () 77 | 78 | else () 79 | message(FATAL_ERROR "你的 MSVC 版本太老了, 请使用 vs2015 或更新版本的 MSVC 编译器. 与时俱进吧, 不要一直使用十年前的编译器.") 80 | endif () 81 | 82 | target_compile_options(ege-common INTERFACE /source-charset:utf-8 /MP ${CPP_COMPILE_OPTIONS} /D_USE_MATH_DEFINES /D__STDC_LIMIT_MACROS "$<$:/DDEBUG>" "$<$:/DNDEBUG>" "$<$:/DNDEBUG>" "$<$:/DNDEBUG>" "$,/MTd,/MT>") 83 | endif () 84 | 85 | if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") 86 | if (CMAKE_HOST_APPLE) 87 | set(osLibDir "macOS") 88 | else () 89 | set(osLibDir "mingw-w64-debian") 90 | endif () 91 | target_compile_options(ege-common INTERFACE -D_FORTIFY_SOURCE=0) 92 | target_link_options(ege-common INTERFACE -mwindows -static -static-libgcc -static-libstdc++) 93 | target_link_libraries(ege-common INTERFACE graphics gdiplus gdi32 imm32 msimg32 ole32 oleaut32 winmm uuid) 94 | endif () 95 | 96 | if (DEFINED osLibDir) 97 | message(STATUS "osLibDir: ${osLibDir}") 98 | target_link_directories(ege-common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/ege/lib/${osLibDir}) 99 | endif () 100 | 101 | 102 | add_executable(demo-Lines demo-Lines.cpp) 103 | target_link_libraries(demo-Lines ege-common) 104 | 105 | add_executable(demo-Teapot demo-Teapot.cpp) 106 | target_link_libraries(demo-Teapot ege-common) 107 | 108 | add_executable(demo-SceneRoaming demo-SceneRoaming.cpp) 109 | target_link_libraries(demo-SceneRoaming ege-common) 110 | -------------------------------------------------------------------------------- /demo-Lines.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: wysaid 3 | * Mail: admin@wysaid.org 4 | * Blog: http://blog.wysaid.org 5 | */ 6 | 7 | #include "cgeMat.h" 8 | #include "cgeVec.h" 9 | #include "graphics.h" 10 | #include 11 | 12 | using namespace CGE; 13 | 14 | class Object3d 15 | { 16 | public: 17 | Object3d() 18 | { 19 | //把下面的0(1)换成1(0)可以切换两种视图 20 | #if 1 21 | m_matProj = Mat4::makePerspective(M_PI / 4.0f, 4.0f / 3.0f, 1.0, 1000.0f); 22 | m_matModelView = Mat4::makeLookAt(0.0f, 0.0f, 800.0f, 0.0f, 0.0f, -1000.0f, 0.0f, 1.0f, 0.0f); 23 | #else 24 | m_matProj = Mat4::makeOrtho(-400.0f, 400.0f, -300.0f, 300.0f, -1.0f, 1.0f); 25 | m_matModelView.loadIdentity(); 26 | #endif 27 | } 28 | ~Object3d() {} 29 | 30 | void render(float x, float y) 31 | { 32 | std::vector vec; 33 | Mat4 mvp = m_matProj * m_matModelView; 34 | for(auto t = m_vec.begin(); t != m_vec.end(); ++t) 35 | { 36 | Vec2f coord; 37 | Mat4::projectM4f(*t, mvp, coord, 800.0f, 600.0f); 38 | vec.push_back(coord); 39 | } 40 | 41 | for(auto t1 = vec.begin(); t1 != vec.end(); ++t1) 42 | { 43 | for(auto t2 = vec.begin(); t2 != vec.end(); ++t2) 44 | { 45 | line(x + t1->x(), y + t1->y(), x + t2->x(), y + t2->y()); 46 | } 47 | // outtextxy(x + t1->x(), y + t1->y(), '@'); 48 | } 49 | 50 | 51 | // for(auto t = m_vecTmp.begin()+1; t < m_vecTmp.end(); ++t) 52 | // { 53 | // 54 | // line(x + (t-1)->x(), y + (t-1)->y(), x + t->x(), y + t->y()); 55 | // } 56 | // if(!m_vecTmp.empty()) 57 | // { 58 | // line(x + m_vecTmp[0].x(), y + m_vecTmp[0].y(), x + m_vecTmp[m_vecTmp.size()-1].x(), y + m_vecTmp[m_vecTmp.size()-1].y()); 59 | // } 60 | } 61 | 62 | void pushPoint(Vec3f pnt) 63 | { 64 | m_vec.push_back(pnt); 65 | } 66 | 67 | void pushPoints(Vec3f* pnt, int n) 68 | { 69 | for(int i = 0; i != n; ++i) 70 | { 71 | m_vec.push_back(pnt[i]); 72 | } 73 | } 74 | 75 | void pushPoint(float x, float y, float z) 76 | { 77 | m_vec.push_back(Vec3f(x, y, z)); 78 | } 79 | 80 | void rotate(float rad, float x, float y, float z) 81 | { 82 | m_matModelView.rotate(rad, x, y, z); 83 | } 84 | 85 | void rotateX(float rad) 86 | { 87 | m_matModelView.rotateX(rad); 88 | } 89 | 90 | void rotateY(float rad) 91 | { 92 | m_matModelView.rotateY(rad); 93 | } 94 | 95 | void rotateZ(float rad) 96 | { 97 | m_matModelView.rotateZ(rad); 98 | } 99 | 100 | void translateZ(float z) 101 | { 102 | m_matModelView.translateZ(z); 103 | } 104 | 105 | void clear() { m_vec.clear(); } 106 | 107 | private: 108 | std::vector m_vec; 109 | Mat4 m_matProj, m_matModelView; 110 | }; 111 | 112 | void getObj(Object3d& obj, float scale) 113 | { 114 | obj.pushPoint(-scale, -scale, 0.0f); 115 | obj.pushPoint(scale, -scale, 0.0f); 116 | obj.pushPoint(scale, scale, 0.0f); 117 | obj.pushPoint(-scale, scale, 0.0f); 118 | } 119 | 120 | void getBox(Object3d& obj, float scale) 121 | { 122 | obj.pushPoint(-scale, -scale, scale); 123 | obj.pushPoint(scale, -scale, scale); 124 | obj.pushPoint(scale, scale, scale); 125 | obj.pushPoint(-scale, scale, scale); 126 | obj.pushPoint(-scale, -scale, -scale); 127 | obj.pushPoint(scale, -scale, -scale); 128 | obj.pushPoint(scale, scale, -scale); 129 | obj.pushPoint(-scale, scale, -scale); 130 | } 131 | 132 | #define RANDOM_SIGN (random(2) == 0 ? -1 : 1) 133 | 134 | void getObject(Object3d& obj, float scale) 135 | { 136 | for(int i = 0; i != 40; ++i) 137 | { 138 | obj.pushPoint(RANDOM_SIGN*randomf()*scale, RANDOM_SIGN*randomf()*scale, RANDOM_SIGN*randomf()*scale); 139 | } 140 | } 141 | 142 | 143 | bool mouseFunc(Object3d& obj) 144 | { 145 | if(!mousemsg()) return false; 146 | do 147 | { 148 | static int s_lastX, s_lastY; 149 | static int s_bIsDown = false; 150 | mouse_msg msg = getmouse(); 151 | switch (msg.msg) 152 | { 153 | case mouse_msg_down: 154 | s_lastX = msg.x; 155 | s_lastY = msg.y; 156 | s_bIsDown = true; 157 | break; 158 | case mouse_msg_up: 159 | s_bIsDown = false; 160 | break; 161 | case mouse_msg_wheel: 162 | obj.translateZ(msg.wheel / 12.0f); 163 | break; 164 | default: 165 | break; 166 | } 167 | 168 | if(s_bIsDown && msg.is_move()) 169 | { 170 | obj.rotateX((msg.y - s_lastY) / 100.0f); 171 | obj.rotateZ((msg.x - s_lastX) / 100.0f); 172 | s_lastX = msg.x; 173 | s_lastY = msg.y; 174 | } 175 | }while(mousemsg()); 176 | return true; 177 | } 178 | 179 | int main() 180 | { 181 | initgraph(800, 600); 182 | setrendermode(RENDER_MANUAL); 183 | Object3d obj; 184 | Object3d obj2; 185 | getObject(obj, 300.0f); 186 | getBox(obj2, 50.0f); 187 | randomize(); 188 | // obj2.translateZ(-500.0f); 189 | int i = 0; 190 | static bool s_useBlur = false; 191 | float x = 0.0f, y = 0.0f; 192 | float dx = randomf()* 5.0f + 1.0f, dy = randomf()* 5.0f + 1.0f; 193 | float radX = randomf()*10.0f + 0.001f, radY = randomf() * 10.0f, radZ = randomf() * 10.0f; 194 | setbkmode(TRANSPARENT); 195 | for(; is_run(); delay_fps(60)) 196 | { 197 | if(s_useBlur) imagefilter_blurring(0, 0x80, 0x100); 198 | else cleardevice(); 199 | mouseFunc(obj); 200 | 201 | obj.render(0, 0); 202 | outtextxy(20, 10, "点击空格键启用模糊滤镜,按回车随机生成模型"); 203 | setcolor(WHITE); 204 | obj2.rotate(0.05f, radX, radY, radZ); 205 | 206 | obj2.render(x, y); 207 | setcolor(HSVtoRGB(i*2, 1.0f, 1.0f)); 208 | 209 | x += dx; 210 | y += dy; 211 | 212 | if(x < 0.0f || x > 800.0f) 213 | { 214 | dx = -dx; 215 | x += dx; 216 | } 217 | if(y < 0.0f || y > 600.0f) 218 | { 219 | dy = -dy; 220 | y += dy; 221 | } 222 | if(++i > 360) 223 | { 224 | i = 0; 225 | // obj.clear(); 226 | // getObject(obj, 300.0f); 227 | } 228 | if(kbhit()) 229 | { 230 | switch (getch()) 231 | { 232 | case ' ': 233 | s_useBlur = !s_useBlur; 234 | break; 235 | case '\r': 236 | obj.clear(); 237 | getObject(obj, 300.0f); 238 | break; 239 | default: 240 | break; 241 | } 242 | } 243 | } 244 | closegraph(); 245 | return 0; 246 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Load Project", 8 | "type": "shell", 9 | "command": "bash", 10 | "args": [ 11 | "-l", 12 | "-c", 13 | "mkdir -p build && cd build && cmake .." 14 | ], 15 | "options": { 16 | "cwd": "${workspaceFolder}" 17 | }, 18 | "group": "build", 19 | "problemMatcher": "$gcc", 20 | "windows": { 21 | "command": "cmd", 22 | "args": [ 23 | "/c", 24 | "(if not exist build (mkdir build) ) & (cd build && cmake ..)" 25 | ], 26 | "options": { 27 | "cwd": "${workspaceFolder}" 28 | } 29 | } 30 | }, 31 | { 32 | "label": "Build Project (Debug)", 33 | "type": "shell", 34 | "command": "bash", 35 | "args": [ 36 | "-l", 37 | "-c", 38 | "(test -d build || (mkdir -p build && pushd . && cd build && cmake .. && popd) ); cmake --build build --parallel $(nproc)" 39 | ], 40 | "options": { 41 | "cwd": "${workspaceFolder}" 42 | }, 43 | "group": "build", 44 | "problemMatcher": "$gcc", 45 | "windows": { 46 | "command": "cmd", 47 | "args": [ 48 | "/c", 49 | "(if not exist \"build\" (mkdir build && cd build && cmake ..) ) & cmake --build \"${workspaceFolder}/build\" --parallel %NUMBER_OF_PROCESSORS%" 50 | ], 51 | "options": { 52 | "cwd": "${workspaceFolder}" 53 | } 54 | } 55 | }, 56 | { 57 | "label": "Build Project (Release)", 58 | "type": "shell", 59 | "command": "bash", 60 | "args": [ 61 | "-l", 62 | "-c", 63 | "(test -d build || (mkdir -p build && pushd . && cd build && cmake .. && popd) ); cmake --build build --config Release --parallel $(nproc)" 64 | ], 65 | "options": { 66 | "cwd": "${workspaceFolder}" 67 | }, 68 | "group": "build", 69 | "problemMatcher": "$gcc", 70 | "windows": { 71 | "command": "cmd", 72 | "args": [ 73 | "/c", 74 | "(if not exist \"build\" (mkdir build && cd build && cmake ..) ) & cmake --build \"${workspaceFolder}/build\" --config Release --parallel %NUMBER_OF_PROCESSORS%" 75 | ], 76 | "options": { 77 | "cwd": "${workspaceFolder}" 78 | } 79 | } 80 | }, 81 | { 82 | "label": "Load And Build Project (Debug)", 83 | "type": "shell", 84 | "command": "echo", 85 | "args": [ 86 | "Load And Build Project (Debug) - Done", 87 | ], 88 | "group": "build", 89 | "dependsOn": [ 90 | "Load Project", 91 | "Build Project (Debug)" 92 | ], 93 | "dependsOrder": "sequence", 94 | }, 95 | { 96 | "label": "Load And Build Project (Release)", 97 | "type": "shell", 98 | "command": "echo", 99 | "args": [ 100 | "Load And Build Project (Release) - Done", 101 | ], 102 | "group": "build", 103 | "dependsOn": [ 104 | "Load Project", 105 | "Build Project (Release)" 106 | ], 107 | "dependsOrder": "sequence", 108 | }, 109 | { 110 | "label": "Run demo-SceneRoaming (Debug)", 111 | "type": "shell", 112 | "command": "bash", 113 | "args": [ 114 | "-l", 115 | "-c", 116 | "if command -v wine64; then wine64 demo-SceneRoaming.exe; else wine demo-SceneRoaming.exe; fi" 117 | ], 118 | "options": { 119 | "cwd": "${workspaceFolder}/build" 120 | }, 121 | "group": "build", 122 | "problemMatcher": "$gcc", 123 | "dependsOn": [ 124 | "Build Project (Debug)" 125 | ], 126 | "windows": { 127 | "command": "cmd", 128 | "args": [ 129 | "/c", 130 | "demo-SceneRoaming.exe" 131 | ], 132 | "options": { 133 | "cwd": "${workspaceFolder}/build/Debug" 134 | } 135 | } 136 | }, 137 | { 138 | "label": "Run demo-SceneRoaming (Release)", 139 | "type": "shell", 140 | "command": "bash", 141 | "args": [ 142 | "-l", 143 | "-c", 144 | "if command -v wine64; then wine64 demo-SceneRoaming.exe; else wine demo-SceneRoaming.exe; fi" 145 | ], 146 | "options": { 147 | "cwd": "${workspaceFolder}/build" 148 | }, 149 | "group": "build", 150 | "problemMatcher": "$gcc", 151 | "dependsOn": [ 152 | "Build Project (Release)" 153 | ], 154 | "windows": { 155 | "command": "cmd", 156 | "args": [ 157 | "/c", 158 | "demo-SceneRoaming.exe" 159 | ], 160 | "options": { 161 | "cwd": "${workspaceFolder}/build/Release" 162 | } 163 | } 164 | }, 165 | { 166 | "label": "Clean Project", 167 | "type": "shell", 168 | "command": "bash", 169 | "args": [ 170 | "-l", 171 | "-c", 172 | "git clean -fdx build || rm -rf build" 173 | ], 174 | "options": { 175 | "cwd": "${workspaceFolder}" 176 | }, 177 | "group": "build", 178 | "problemMatcher": "$gcc", 179 | "windows": { 180 | "command": "cmd", 181 | "args": [ 182 | "/c", 183 | "git clean -fdx build || rmdir /s /q build" 184 | ], 185 | "options": { 186 | "cwd": "${workspaceFolder}" 187 | } 188 | } 189 | } 190 | ] 191 | } -------------------------------------------------------------------------------- /ege/include/ege/sys_edit.h: -------------------------------------------------------------------------------- 1 | #ifndef EGE_SYS_EDIT_H 2 | #define EGE_SYS_EDIT_H 3 | 4 | #include "egecontrolbase.h" 5 | 6 | #define EGE_CONVERT_TO_WSTR_WITH(mbStr, block) \ 7 | { \ 8 | int bufsize = ::MultiByteToWideChar(::ege::getcodepage(), 0, mbStr, -1, NULL, 0); \ 9 | WCHAR* wStr = new WCHAR[bufsize]; \ 10 | ::MultiByteToWideChar(::ege::getcodepage(), 0, mbStr, -1, &wStr[0], bufsize); \ 11 | block delete wStr; \ 12 | } 13 | 14 | namespace ege 15 | { 16 | 17 | class sys_edit : public egeControlBase 18 | { 19 | public: 20 | CTL_PREINIT(sys_edit, egeControlBase) 21 | { 22 | // do sth. before sub objects' construct function call 23 | } 24 | 25 | CTL_PREINITEND; 26 | 27 | sys_edit(CTL_DEFPARAM) : CTL_INITBASE(egeControlBase) 28 | { 29 | CTL_INIT; // must be the first linef 30 | directdraw(true); 31 | m_hwnd = NULL; 32 | } 33 | 34 | ~sys_edit() { destroy(); } 35 | 36 | int create(bool multiline = false, int scrollbar = 2) 37 | { 38 | if (m_hwnd) { 39 | destroy(); 40 | } 41 | 42 | msg_createwindow msg = {NULL}; 43 | msg.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); 44 | msg.classname = L"EDIT"; 45 | msg.id = egeControlBase::allocId(); 46 | msg.style = WS_CHILD | WS_BORDER | ES_LEFT | ES_WANTRETURN; 47 | 48 | if (multiline) { 49 | msg.style |= ES_MULTILINE | WS_VSCROLL; 50 | } else { 51 | msg.style |= ES_AUTOHSCROLL; 52 | } 53 | 54 | msg.exstyle = WS_EX_CLIENTEDGE; // | WS_EX_STATICEDGE; 55 | msg.param = this; 56 | 57 | ::PostMessageW(getHWnd(), WM_USER + 1, 1, (LPARAM)&msg); 58 | ::WaitForSingleObject(msg.hEvent, INFINITE); 59 | 60 | m_hwnd = msg.hwnd; 61 | m_hFont = NULL; 62 | m_hBrush = NULL; 63 | m_color = 0x0; 64 | m_bgcolor = 0xFFFFFF; 65 | 66 | ::SetWindowLongPtrW(m_hwnd, GWLP_USERDATA, (LONG_PTR)this); 67 | m_callback = ::GetWindowLongPtrW(m_hwnd, GWLP_WNDPROC); 68 | ::SetWindowLongPtrW(m_hwnd, GWLP_WNDPROC, (LONG_PTR)getProcfunc()); 69 | { 70 | WCHAR fontname[] = L"SimSun"; 71 | setfont(12, 6, fontname); 72 | } 73 | visible(false); 74 | 75 | ::CloseHandle(msg.hEvent); 76 | 77 | return 0; 78 | } 79 | 80 | int destroy() 81 | { 82 | if (m_hwnd) { 83 | visible(false); 84 | msg_createwindow msg = {NULL}; 85 | msg.hwnd = m_hwnd; 86 | msg.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); 87 | ::SendMessage(m_hwnd, WM_SETFONT, 0, 0); 88 | ::DeleteObject(m_hFont); 89 | ::PostMessageW(getHWnd(), WM_USER + 1, 0, (LPARAM)&msg); 90 | ::WaitForSingleObject(msg.hEvent, INFINITE); 91 | ::CloseHandle(msg.hEvent); 92 | if (m_hBrush) { 93 | ::DeleteObject(m_hBrush); 94 | } 95 | m_hwnd = NULL; 96 | return 1; 97 | } 98 | return 0; 99 | } 100 | 101 | LRESULT onMessage(UINT message, WPARAM wParam, LPARAM lParam); 102 | 103 | void visible(bool bvisible) 104 | { 105 | egeControlBase::visible(bvisible); 106 | ::ShowWindow(m_hwnd, (int)bvisible); 107 | } 108 | 109 | void setfont(int h, int w, LPCSTR fontface) 110 | { 111 | EGE_CONVERT_TO_WSTR_WITH(fontface, { setfont(h, w, wStr); }); 112 | } 113 | 114 | void setfont(int h, int w, LPCWSTR fontface) 115 | { 116 | LOGFONTW lf = {0}; 117 | lf.lfHeight = h; 118 | lf.lfWidth = w; 119 | lf.lfEscapement = 0; 120 | lf.lfOrientation = 0; 121 | lf.lfWeight = FW_DONTCARE; 122 | lf.lfItalic = 0; 123 | lf.lfUnderline = 0; 124 | lf.lfStrikeOut = 0; 125 | lf.lfCharSet = DEFAULT_CHARSET; 126 | lf.lfOutPrecision = OUT_DEFAULT_PRECIS; 127 | lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; 128 | lf.lfQuality = DEFAULT_QUALITY; 129 | lf.lfPitchAndFamily = DEFAULT_PITCH; 130 | lstrcpyW(lf.lfFaceName, fontface); 131 | HFONT hFont = CreateFontIndirectW(&lf); 132 | if (hFont) { 133 | ::SendMessageW(m_hwnd, WM_SETFONT, (WPARAM)hFont, 0); 134 | ::DeleteObject(m_hFont); 135 | m_hFont = hFont; 136 | } 137 | } 138 | 139 | void move(int x, int y) 140 | { 141 | egeControlBase::move(x, y); 142 | ::MoveWindow(m_hwnd, m_x, m_y, m_w, m_h, TRUE); 143 | } 144 | 145 | void size(int w, int h) 146 | { 147 | egeControlBase::size(w, h); 148 | ::MoveWindow(m_hwnd, m_x, m_y, m_w, m_h, TRUE); 149 | } 150 | 151 | void settext(LPCSTR text) 152 | { 153 | EGE_CONVERT_TO_WSTR_WITH(text, { settext(wStr); }); 154 | } 155 | 156 | void settext(LPCWSTR text) { ::SendMessageW(m_hwnd, WM_SETTEXT, 0, (LPARAM)text); } 157 | 158 | void gettext(int maxlen, LPSTR text) { ::SendMessageA(m_hwnd, WM_GETTEXT, (WPARAM)maxlen, (LPARAM)text); } 159 | 160 | void gettext(int maxlen, LPWSTR text) { ::SendMessageW(m_hwnd, WM_GETTEXT, (WPARAM)maxlen, (LPARAM)text); } 161 | 162 | void setmaxlen(int maxlen) { ::SendMessageW(m_hwnd, EM_LIMITTEXT, (WPARAM)maxlen, 0); } 163 | 164 | void setcolor(color_t color) 165 | { 166 | m_color = color; 167 | ::InvalidateRect(m_hwnd, NULL, TRUE); 168 | } 169 | 170 | void setbgcolor(color_t bgcolor) 171 | { 172 | m_bgcolor = bgcolor; 173 | //::RedrawWindow(m_hwnd, NULL, NULL, RDW_INVALIDATE); 174 | ::InvalidateRect(m_hwnd, NULL, TRUE); 175 | } 176 | 177 | void setreadonly(bool readonly) 178 | { 179 | ::SendMessageW(m_hwnd, EM_SETREADONLY, (WPARAM)readonly, 0); 180 | ::InvalidateRect(m_hwnd, NULL, TRUE); 181 | } 182 | 183 | void setfocus() 184 | { 185 | msg_createwindow msg = {NULL}; 186 | msg.hwnd = m_hwnd; 187 | msg.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); 188 | ::PostMessageW(getHWnd(), WM_USER + 2, 0, (LPARAM)&msg); 189 | ::WaitForSingleObject(msg.hEvent, INFINITE); 190 | } 191 | 192 | protected: 193 | HWND m_hwnd; 194 | HFONT m_hFont; 195 | HBRUSH m_hBrush; 196 | color_t m_color; 197 | color_t m_bgcolor; 198 | LONG_PTR m_callback; 199 | }; 200 | 201 | #undef EGE_CONVERT_TO_WSTR_WITH 202 | 203 | } // namespace ege 204 | #endif /*EGE_SYS_EDIT_H*/ 205 | -------------------------------------------------------------------------------- /ege/include/ege/egecontrolbase.h: -------------------------------------------------------------------------------- 1 | #ifndef EGECONTROLBASE_H 2 | #define EGECONTROLBASE_H 3 | 4 | #include "../ege.h" 5 | 6 | namespace ege 7 | { 8 | 9 | class PushTarget 10 | { 11 | public: 12 | PushTarget() { m_target = gettarget(); } 13 | 14 | PushTarget(PIMAGE target) 15 | { 16 | m_target = gettarget(); 17 | settarget(target); 18 | } 19 | 20 | ~PushTarget() { settarget(m_target); } 21 | 22 | private: 23 | PIMAGE m_target; 24 | }; 25 | 26 | #define CTL_PREINIT(classname, parent) \ 27 | struct preinit_obj \ 28 | { \ 29 | preinit_obj(classname* This, int inheritlevel) \ 30 | { \ 31 | This->pre_init(inheritlevel); \ 32 | } \ 33 | } egecontrolbase_preinit_obj; \ 34 | enum inherit_e \ 35 | { \ 36 | inherit_level_e = parent::inherit_level_e + 1, \ 37 | }; \ 38 | static void firstinit(ege::egeControlBase* This) \ 39 | { \ 40 | ((classname*)This)->m_inheritlevel = 1; \ 41 | } \ 42 | void pre_init(int inheritlevel) \ 43 | { \ 44 | (void)inheritlevel; 45 | 46 | #define CTL_PREINITEND } 47 | #define CTL_DEFPARAM int inherit = inherit_level_e, ege::egeControlBase *pParent = NULL 48 | #define CTL_INITBASE(parent) \ 49 | egecontrolbase_preinit_obj(this, inherit_level_e), parent(inherit, (ege::egeControlBase*)pParent) 50 | #define CTL_INIT \ 51 | InitObject iobj(this, inherit_level_e); \ 52 | ege::PushTarget _pushtarget(buf()); 53 | 54 | #define EGECTRL_INITEND() } 55 | 56 | class egeControlBase 57 | { 58 | public: 59 | enum ROP 60 | { 61 | COPY = SRCCOPY, 62 | XOR = SRCINVERT, 63 | AND = SRCAND, 64 | OR = SRCPAINT, 65 | }; 66 | 67 | enum blendmode_e 68 | { 69 | SOLIDCOPY = 0, 70 | ALPHABLEND = 1, 71 | }; 72 | 73 | enum inherit_e 74 | { 75 | inherit_level_e = 0, 76 | }; 77 | 78 | egeControlBase(); 79 | egeControlBase(int inherit, egeControlBase* pParent); 80 | ~egeControlBase(); 81 | 82 | virtual LRESULT onMessage(UINT message, WPARAM wParam, LPARAM lParam) 83 | { 84 | (void)message; 85 | (void)wParam; 86 | (void)lParam; 87 | return 0; 88 | } 89 | 90 | virtual int onMouse(int x, int y, int flag) 91 | { 92 | (void)x; 93 | (void)y; 94 | (void)flag; 95 | return 0; 96 | } 97 | 98 | virtual int onKeyDown(int key, int flag) 99 | { 100 | (void)key; 101 | (void)flag; 102 | return 0; 103 | } 104 | 105 | virtual int onKeyUp(int key, int flag) 106 | { 107 | (void)key; 108 | (void)flag; 109 | return 0; 110 | } 111 | 112 | virtual int onKeyChar(int key, int flag) 113 | { 114 | (void)key; 115 | (void)flag; 116 | return 0; 117 | } 118 | 119 | virtual int onUpdate() { return 0; } 120 | 121 | virtual int onGetFocus() { return 0; } 122 | 123 | virtual void onLostFocus() {} 124 | 125 | virtual void onSizing(int* w, int* h) 126 | { 127 | (void)w; 128 | (void)h; 129 | } 130 | 131 | virtual void onSize(int w, int h) 132 | { 133 | (void)w; 134 | (void)h; 135 | } 136 | 137 | virtual void onDraw(PIMAGE pimg) const { (void)pimg; } 138 | 139 | virtual void onResetFilter() 140 | { 141 | setbkcolor(BLACK, m_mainFilter); 142 | cleardevice(m_mainFilter); 143 | } 144 | 145 | virtual void onAddChild(egeControlBase* pChild) { (void)pChild; } 146 | 147 | virtual void onDelChild(egeControlBase* pChild) { (void)pChild; } 148 | 149 | virtual void onIdle() {} 150 | 151 | public: 152 | PIMAGE buf() { return m_mainbuf; } 153 | 154 | PIMAGE filter() { return m_mainFilter; } 155 | 156 | egeControlBase* parent() { return m_parent; } 157 | 158 | PIMAGE buf() const { return m_mainbuf; } 159 | 160 | PIMAGE filter() const { return m_mainFilter; } 161 | 162 | const egeControlBase* parent() const { return m_parent; } 163 | 164 | void blendmode(int mode) { m_AlphablendMode = mode; } 165 | 166 | void setrop(int rop) { m_rop = rop; } 167 | 168 | void directdraw(bool bdraw) { m_bDirectDraw = (bdraw ? 1 : 0); } 169 | bool isdirectdraw() const { return (m_bDirectDraw != 0); } 170 | 171 | void autoredraw(bool bautoredraw) { m_bAutoDraw = (bautoredraw ? 1 : 0); } 172 | bool isautoredraw() const { return (m_bAutoDraw != 0); } 173 | 174 | void visible(bool bvisible) { m_bVisible = (bvisible ? 1 : 0); } 175 | bool isvisible() const { return (m_bVisible != 0); } 176 | 177 | void enable(bool benable) { m_bEnable = (benable ? 1 : 0); } 178 | bool isenable() const { return (m_bEnable != 0); } 179 | 180 | void capture(bool bcapture) { m_bCapture = (bcapture ? 1 : 0); } 181 | bool iscapture() const { return (m_bCapture != 0); } 182 | 183 | void capmouse(bool bcapmouse) { m_bCapMouse = (bcapmouse ? 1 : 0); } 184 | bool iscapmouse() const { return (m_bCapMouse != 0); } 185 | 186 | bool isfocus() const { return (m_bInputFocus != 0); } 187 | 188 | void move(int x, int y) 189 | { 190 | m_x = x; 191 | m_y = y; 192 | } 193 | 194 | void size(int w, int h) 195 | { 196 | onSizing(&w, &h); 197 | m_w = w; 198 | m_h = h; 199 | resize(m_mainbuf, w, h); 200 | resize(m_mainFilter, w, h); 201 | onSize(w, h); 202 | onResetFilter(); 203 | } 204 | 205 | void zorderup(); 206 | void zorderdown(); 207 | void zorderset(int z); 208 | 209 | int getx() const { return m_x; } 210 | int gety() const { return m_y; } 211 | int getw() const { return m_w; } 212 | int geth() const { return m_h; } 213 | int width() const { return m_w; } 214 | int height() const { return m_h; } 215 | 216 | int addchild(egeControlBase* pChild); 217 | int delchild(egeControlBase* pChild); 218 | void draw(PIMAGE pimg); 219 | void update(); 220 | void mouse(int x, int y, int flag); 221 | void keymsgdown(unsigned key, int flag); 222 | void keymsgup(unsigned key, int flag); 223 | void keymsgchar(unsigned key, int flag); 224 | 225 | bool operator<(const egeControlBase& pbase) const 226 | { 227 | if (m_zOrderLayer != pbase.m_zOrderLayer) { 228 | return m_zOrderLayer < pbase.m_zOrderLayer; 229 | } 230 | if (m_zOrder == pbase.m_zOrder) { 231 | return this < &pbase; 232 | } else { 233 | return m_zOrder < pbase.m_zOrder; 234 | } 235 | } 236 | 237 | protected: 238 | int allocId(); 239 | int allocZorder(); 240 | 241 | class InitObject 242 | { 243 | public: 244 | InitObject(egeControlBase* pThis, int inherit_level); 245 | ~InitObject(); 246 | 247 | private: 248 | egeControlBase* m_this; 249 | int m_inherit_level; 250 | }; 251 | 252 | void (*m_preinit_func)(egeControlBase*); 253 | 254 | private: 255 | void init(egeControlBase* parent); 256 | void fixzorder(); 257 | void sortzorder(); 258 | #if _MSC_VER <= 1200 259 | public: 260 | #endif 261 | void initok(); 262 | 263 | private: 264 | PIMAGE m_mainbuf; 265 | PIMAGE m_mainFilter; 266 | 267 | protected: 268 | int m_bVisible; 269 | int m_bEnable; 270 | int m_bAutoDraw; 271 | int m_bCapture; 272 | int m_bInputFocus; 273 | int m_bCapMouse; 274 | int m_zOrderLayer; 275 | int m_zOrder; 276 | int m_allocId; 277 | int m_allocZorder; 278 | 279 | private: 280 | egeControlBase* m_parent; 281 | static int s_maxchildid; 282 | 283 | #ifdef EGE_GRAPH_LIB_BUILD 284 | public: 285 | #else 286 | private: 287 | #endif 288 | void* m_childmap; 289 | void* m_childzorder; 290 | 291 | protected: 292 | int m_x, m_y; 293 | int m_w, m_h; 294 | 295 | protected: 296 | DWORD m_rop; 297 | int m_AlphablendMode; 298 | int m_bDirectDraw; 299 | #if _MSC_VER <= 1200 300 | public: 301 | #endif 302 | int m_inheritlevel; 303 | }; 304 | 305 | } /* namespace ege */ 306 | 307 | #endif /* EGECONTROLBASE_H */ 308 | -------------------------------------------------------------------------------- /ege/include/ege/button.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file button.h 3 | * @brief the EGE control:button 4 | * @author StudyC.cn@gmail.com 5 | * @date 2011-08-09 6 | */ 7 | #ifndef EGE_BUTTON_H 8 | #define EGE_BUTTON_H 9 | 10 | #include "egecontrolbase.h" 11 | 12 | #include 13 | 14 | #ifdef DEBUG 15 | #include "ege/label.h" 16 | #else 17 | #define logout(msg) 18 | #endif 19 | 20 | namespace ege 21 | { 22 | 23 | class button : public egeControlBase 24 | { 25 | public: 26 | virtual int onKeyDown(int key, int flag) 27 | { 28 | if ((key == 13) || (key == 32)) { 29 | _pushed = true; 30 | redraw(); 31 | } 32 | return 0; 33 | } 34 | 35 | virtual int onKeyUp(int key, int flag) 36 | { 37 | if (((key == 13) || (key == 32)) && _pushed) { 38 | if (_on_click) { 39 | if (!_on_click(callback_param)) { 40 | onClick(); 41 | } 42 | } else { 43 | onClick(); 44 | } 45 | } 46 | _pushed = false; 47 | redraw(); 48 | return 0; 49 | } 50 | 51 | virtual int onMouse(int x, int y, int flag) 52 | { 53 | if ((flag & mouse_flag_left) && (flag & mouse_msg_down)) { 54 | capmouse(true); 55 | _pushed = true; 56 | redraw(); 57 | } else if ((flag & mouse_flag_left) && (flag & mouse_msg_up)) { 58 | if (_pushed) { 59 | if (_on_click) { 60 | if (!_on_click(callback_param)) { 61 | onClick(); 62 | } 63 | } else { 64 | onClick(); 65 | } 66 | capmouse(false); 67 | _pushed = false; 68 | } 69 | redraw(); 70 | } 71 | return 0; 72 | } 73 | 74 | virtual int onUpdate() { return 0; } 75 | 76 | virtual int onGetFocus() { return 0; } 77 | 78 | virtual void onLostFocus() 79 | { 80 | _pushed = false; 81 | redraw(); 82 | } 83 | 84 | virtual void onSizing(int* w, int* h) 85 | { 86 | // egeControlBase::onSizing(w,h); 87 | } 88 | 89 | virtual void onSize(int w, int h) 90 | { 91 | // egeControlBase::onSize(w,h); 92 | updatesidewidth(); 93 | redraw(); 94 | } 95 | 96 | virtual void onDraw(PIMAGE pimg) const {} 97 | 98 | virtual void onResetFilter() {} 99 | 100 | // virtual void onAddChild(egeControlBase* pChild) {} 101 | // virtual void onDelChild(egeControlBase* pChild) {} 102 | // virtual void onIdle() {} 103 | // init 104 | CTL_PREINIT(button, egeControlBase) 105 | { 106 | // do sth. before sub objects' construct function call 107 | } 108 | 109 | CTL_PREINITEND; 110 | 111 | button(CTL_DEFPARAM) : CTL_INITBASE(egeControlBase) 112 | { 113 | CTL_INIT; // must be the first line 114 | size(64, 32); 115 | _font_height = 12; 116 | strcpy(_face, "SimSun"); 117 | _line_color = BLACK; 118 | _bg_color = EGERGB(100, 100, 100); 119 | _text_color = BLACK; 120 | _shadow_color = EGERGB(50, 50, 50); 121 | 122 | updatesidewidth(); 123 | 124 | _on_click = NULL; 125 | callback_param = NULL; 126 | _pushed = false; 127 | _alpha = 0xff; 128 | #ifdef DEBUG 129 | _logger = NULL; 130 | #endif 131 | // redraw(); 132 | // blendmode(true); 133 | } 134 | 135 | virtual void onClick() {} 136 | 137 | virtual void redraw() const 138 | { 139 | PushTarget targer(buf()); 140 | setbkcolor_f(RED); 141 | setcolor(RED); 142 | cleardevice(); 143 | setbkmode(TRANSPARENT); 144 | setfillstyle(_bg_color, SOLID_FILL); 145 | bar(0, 0, getw() - 1, geth() - 1); 146 | setfont(_font_height, 0, _face); 147 | setcolor(_text_color); 148 | 149 | // settextjustify(LEFT_TEXT,CENTER_TEXT); 150 | // outtextrect(_side_width, _side_width, getw()-_side_width, geth()-_side_width, _caption); 151 | // outtextrect(0, 0, getw(), geth(), _caption); 152 | int x = (getw() - textwidth(_caption)) / 2; 153 | int y = (geth() - textheight(_caption)) / 2; 154 | 155 | outtextxy(x, y, _caption); 156 | setbkcolor(_line_color); 157 | rectangle(0, 0, getw(), geth()); 158 | rectangle(_side_width, _side_width, getw() - _side_width, geth() - _side_width); 159 | setfillstyle(_shadow_color, SOLID_FILL); 160 | 161 | if (_pushed) { 162 | int points[12] = { 163 | 0, 164 | 0, 165 | getw() - 1, 166 | 0, 167 | getw() - _side_width, 168 | _side_width - 1, 169 | _side_width - 1, 170 | _side_width - 1, 171 | _side_width - 1, 172 | geth() - _side_width - 1, 173 | 0, 174 | geth() - 1, 175 | }; 176 | fillpoly(6, points); 177 | } else { 178 | int points[12] = { 179 | 0, 180 | geth() - 1, 181 | _side_width - 1, 182 | geth() - _side_width, 183 | getw() - _side_width, 184 | geth() - _side_width, 185 | getw() - _side_width, 186 | _side_width - 1, 187 | getw() - 1, 188 | 0, 189 | getw() - 1, 190 | geth() - 1, 191 | }; 192 | fillpoly(6, points); 193 | } 194 | 195 | line(getw() - _side_width, _side_width, getw(), 0); 196 | line(_side_width - 1, geth() - _side_width, 0, geth()); 197 | // line(getw()-_side_width, geth()-_side_width, getw(), geth()); 198 | // line(0,0, _side_width, _side_width); 199 | setbkcolor_f(EGERGB(_alpha, _alpha, _alpha), filter()); 200 | cleardevice(filter()); 201 | } 202 | 203 | void alpha(int alpha) 204 | { 205 | if (alpha < 0) { 206 | _alpha = 0; 207 | } else if (alpha > 0xff) { 208 | _alpha = 0xff; 209 | } else { 210 | _alpha = alpha; 211 | } 212 | if (_alpha < 0xff) { 213 | blendmode(true); 214 | } else { 215 | blendmode(false); 216 | } 217 | } 218 | 219 | int alpha() const { return _alpha; } 220 | 221 | void bgcolor(COLORREF color) 222 | { 223 | _bg_color = color; 224 | redraw(); 225 | } 226 | 227 | COLORREF bgcolor() const { return _bg_color; } 228 | 229 | 230 | void callback(int (*fun)(void*), void* param) 231 | { 232 | callback_param = param; 233 | _on_click = fun; 234 | redraw(); 235 | } 236 | 237 | template T callback() const { return _on_click; } 238 | 239 | void caption(const char* text) 240 | { 241 | strcpy(_caption, text); 242 | redraw(); 243 | } 244 | 245 | const char* caption() const 246 | { 247 | return _caption; 248 | // redraw(); 249 | } 250 | 251 | void font(const char* fontface) 252 | { 253 | strcpy(_face, fontface); 254 | redraw(); 255 | } 256 | 257 | const char* font() const 258 | { 259 | return _face; 260 | // redraw(); 261 | } 262 | 263 | void fontsize(int height) 264 | { 265 | _font_height = height; 266 | redraw(); 267 | } 268 | 269 | int fontsize() const { return _font_height; } 270 | 271 | void linecolor(COLORREF color) 272 | { 273 | _line_color = color; 274 | redraw(); 275 | } 276 | 277 | COLORREF linecolor() const { return _line_color; } 278 | #ifdef DEBUG 279 | 280 | void logger(label* logger) { _logger = logger; } 281 | 282 | label* logger() const { return _logger; } 283 | #endif 284 | 285 | void shadowcolor(COLORREF color) 286 | { 287 | _shadow_color = color; 288 | redraw(); 289 | } 290 | 291 | 292 | COLORREF shadowcolor() const { return _shadow_color; } 293 | 294 | void textcolor(COLORREF color) 295 | { 296 | _text_color = color; 297 | redraw(); 298 | } 299 | 300 | COLORREF textcolor() const { return _text_color; } 301 | 302 | protected: 303 | void updatesidewidth() 304 | { 305 | _side_width = ((geth() < getw()) ? geth() : getw()) * 0.2; 306 | } 307 | 308 | #ifdef DEBUG 309 | void logout(const char* msg) 310 | { 311 | if (_logger) { 312 | _logger->setcaption(msg); 313 | } 314 | } 315 | #endif 316 | bool _pushed; 317 | int (*_on_click)(void*); 318 | char _caption[1024]; 319 | char _face[32]; 320 | COLORREF _line_color; 321 | COLORREF _bg_color; 322 | COLORREF _text_color; 323 | COLORREF _shadow_color; 324 | int _side_width; 325 | int _font_height; 326 | int _alpha; 327 | void* callback_param; 328 | #ifdef DEBUG 329 | label* _logger; 330 | #endif 331 | }; 332 | 333 | } // namespace ege 334 | 335 | #endif /* EGE_BUTTON_H */ 336 | -------------------------------------------------------------------------------- /algorithm/cgeScene.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cgeScene.h 3 | * 4 | * Created on: 2014-10-27 5 | * Author: wysaid 6 | * Mail: admin@wysaid.org 7 | */ 8 | 9 | #ifndef _CGE_SCENE_H_ 10 | #define _CGE_SCENE_H_ 11 | 12 | #include "cgeMat.h" 13 | #include 14 | 15 | namespace CGE 16 | { 17 | #ifndef CGE_MIN 18 | 19 | template 20 | inline Type CGE_MIN(Type a, Type b) 21 | { 22 | return a < b ? a : b; 23 | } 24 | 25 | #endif 26 | 27 | #ifndef CGE_MAX 28 | 29 | template 30 | inline Type CGE_MAX(Type a, Type b) 31 | { 32 | return a > b ? a : b; 33 | } 34 | 35 | #endif 36 | 37 | #ifndef CGE_MID 38 | 39 | template 40 | inline Type CGE_MID(Type n, Type vMin, Type vMax) 41 | { 42 | if (n < vMin) 43 | n = vMin; 44 | else if (n > vMax) 45 | n = vMax; 46 | return n; 47 | } 48 | 49 | #endif 50 | 51 | #ifndef CGE_MIX 52 | 53 | template 54 | inline auto CGE_MIX(OpType a, OpType b, MixType value) -> decltype(a - a * value + b * value) 55 | { 56 | return a - a * value + b * value; 57 | } 58 | 59 | #endif 60 | 61 | //辅助类, 提供场景漫游公共方法以及参数 62 | class SceneInterfaceHelper 63 | { 64 | protected: 65 | SceneInterfaceHelper() : m_eye(0.0f, 0.0f), m_lookDir(0.0f, 1000.0f), m_eyeZ(0.0f), m_lookZ(0.0f), m_dirLen(1000.0f), m_fovyRad(M_PI / 4.0f), m_zNear(1.0f), m_zFar(1000.0f), m_upDirRot(0.0f) {} 66 | 67 | public: 68 | 69 | inline Mat4& modelViewMatrix() { return m_modelViewMatrix; } 70 | inline Mat4& projectionMatrix() { return m_projectionMatrix; } 71 | inline Vec2f& eyeXY() { return m_eye; } 72 | inline float& eyeZ() { return m_eyeZ; } 73 | inline const Vec2f& lookDirXY() const { return m_lookDir; } 74 | inline float& lookDirZ() { return m_lookZ; } 75 | inline float& fovyRad() { return m_fovyRad; } 76 | inline float& zNear() { return m_zNear; } 77 | inline float& zFar() { return m_zFar; } 78 | 79 | static inline float maxLookUp() { return M_PI / 2.4f; } 80 | 81 | inline void updatePerspective() 82 | { 83 | m_projectionMatrix = Mat4::makePerspective(m_fovyRad, m_aspect, m_zNear, m_zFar); 84 | } 85 | 86 | inline void setEye(const Vec3f& v) 87 | { 88 | m_eye[0] = v[0]; 89 | m_eye[1] = v[1]; 90 | m_eyeZ = v[2]; 91 | } 92 | 93 | inline void lookIn(float rad) 94 | { 95 | m_fovyRad = CGE_MID(m_fovyRad + rad, M_PI / 100.0f, M_PI / 2.0f); 96 | updatePerspective(); 97 | } 98 | 99 | inline void lookInTo(float rad) 100 | { 101 | m_fovyRad = CGE_MID(rad, M_PI / 100.0f, M_PI / 2.0f); 102 | updatePerspective(); 103 | } 104 | 105 | inline void setViewport(float w, float h) { m_aspect = w / h; } 106 | inline void setAspect(float aspect) { m_aspect = aspect; } 107 | 108 | inline void rotateByLookDir(float r) { m_upDirRot = r; } 109 | 110 | protected: 111 | Mat4 m_modelViewMatrix, m_projectionMatrix; 112 | Vec2f m_eye, m_lookDir; 113 | float m_eyeZ, m_lookZ; 114 | float m_dirLen; 115 | 116 | //视景体的视野角度(弧度), 透视投影近裁剪面, 透视投影远裁剪面 117 | float m_fovyRad, m_zNear, m_zFar; 118 | float m_aspect; 119 | float m_upDirRot; 120 | }; 121 | 122 | // SceneInterface 提供场景漫游辅助接口(非必须) 123 | // 124 | // 特别注意, SceneInterface 默认使用 xOy 平面作为漫游地面, z正方向为向上方向 125 | // SceneInterface 仅提供相关矩阵和向量, 不提供任何渲染接口。 126 | class SceneInterface : public SceneInterfaceHelper 127 | { 128 | public: 129 | SceneInterface(float w = 1.0f, float h = 1.0f) : SceneInterfaceHelper() 130 | { 131 | m_aspect = w / h; 132 | updatePerspective(); 133 | updateView(); 134 | } 135 | 136 | inline void updateView() 137 | { 138 | Vec2f center(m_eye + m_lookDir); 139 | float len = m_lookDir.length(); 140 | float tmp = -m_lookZ / len; 141 | Vec2f dirBack(m_lookDir * tmp); 142 | Vec3f upDir(dirBack[0], dirBack[1], len); 143 | if(m_upDirRot != 0.0f) //不需要精确浮点数与0的比较, 这里只是判断是否被置为0 144 | upDir = Mat3::makeRotation(m_upDirRot, m_lookDir[0], m_lookDir[1], m_lookZ) * upDir; 145 | m_modelViewMatrix = Mat4::makeLookAt(m_eye[0], m_eye[1], m_eyeZ, center[0], center[1], m_eyeZ + m_lookZ, upDir[0], upDir[1], upDir[2]); 146 | } 147 | 148 | inline void setEyeXY(const Vec2f& v) 149 | { 150 | m_eye = v; 151 | } 152 | 153 | inline void setEyeZ(float z) 154 | { 155 | m_eyeZ = z; 156 | } 157 | 158 | //注意, 这里设置的是观察方向, 不可为0 159 | inline void setLookdirXY(const Vec2f& v) 160 | { 161 | assert(v[0] || v[1]); 162 | m_lookDir = v * (m_dirLen / v.length()); 163 | } 164 | 165 | inline void setLookdirZ(float z) 166 | { 167 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 168 | m_lookZ = CGE_MID(z, -lookUpMax, lookUpMax); 169 | } 170 | 171 | //同上, 场景漫游中, 不允许朝"正"上方观看(仰头无法形成平角 172 | inline void setLookdir(const Vec3f& v) 173 | { 174 | assert(v[0] || v[1]); 175 | m_lookDir[0] = v[0]; 176 | m_lookDir[1] = v[1]; 177 | m_lookDir.normalize(); 178 | m_lookDir *= m_dirLen; 179 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 180 | m_lookZ = CGE_MID(v[2], -lookUpMax, lookUpMax); 181 | } 182 | 183 | //转动视角, rad(弧度) > 0 时 为向右方向 184 | inline void turn(float rad) 185 | { 186 | m_lookDir = Mat2::makeRotation(rad) * m_lookDir; 187 | } 188 | 189 | //转动视角, rad(弧度) > 0 时 为右边。 190 | inline void turnTo(float rad) 191 | { 192 | m_lookDir = Vec2f(sinf(rad), cosf(rad)) * m_dirLen; 193 | } 194 | 195 | //向上观察, motion计算关系 196 | //向上观察弧度计算公式为: arctan(tan("当前向上弧度") + motion) - "当前向上弧度" 197 | inline void lookUp(float motion) 198 | { 199 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 200 | m_lookZ = CGE_MID(m_lookZ + motion * m_dirLen, -lookUpMax, lookUpMax); 201 | } 202 | 203 | //向上观察到(弧度), 直接仰视到所看弧度 204 | //范围[-PI/2.4, PI/2.4], 约正负75度角 205 | inline void lookUpTo(float rad) 206 | { 207 | m_lookZ = tanf(CGE_MID(rad, -M_PI / 2.4f, M_PI / 2.4f)) * m_dirLen; 208 | } 209 | 210 | inline void goForward(float motion) 211 | { 212 | m_eye += m_lookDir * (motion / m_dirLen); 213 | } 214 | 215 | inline void goBack(float motion) 216 | { 217 | m_eye -= m_lookDir * (motion / m_dirLen); 218 | } 219 | 220 | inline void goLeft(float motion) 221 | { 222 | float m = motion / m_dirLen; 223 | m_eye[0] -= m_lookDir[1] * m; 224 | m_eye[1] += m_lookDir[0] * m; 225 | } 226 | 227 | inline void goRight(float motion) 228 | { 229 | float m = motion / m_dirLen; 230 | m_eye[0] += m_lookDir[1] * m; 231 | m_eye[1] -= m_lookDir[0] * m; 232 | } 233 | }; 234 | 235 | // 使用笛卡尔坐标系来漫游, 使用 xOz 平面作为漫游地面, y正方向为向上方向, 其他部分与SceneInterface相同 236 | class SceneInterfaceDescartes : public SceneInterfaceHelper 237 | { 238 | public: 239 | SceneInterfaceDescartes(float w = 1.0f, float h = 1.0f) : SceneInterfaceHelper() 240 | { 241 | m_aspect = w / h; 242 | updatePerspective(); 243 | updateView(); 244 | } 245 | 246 | inline void updateView() 247 | { 248 | Vec2f center(m_lookDir + Vec2f(m_eye[0], m_eyeZ)); 249 | float len = m_lookDir.length(); 250 | float tmp = -m_lookZ / len; 251 | Vec2f dirBack(m_lookDir * tmp); 252 | Vec3f upDir(dirBack[0], len, dirBack[1]); 253 | if(m_upDirRot != 0.0f) //不需要精确浮点数与0的比较, 这里只是判断是否被置为0 254 | upDir = Mat3::makeRotation(m_upDirRot, m_lookDir[0], m_lookZ, m_lookDir[1]) * upDir; 255 | m_modelViewMatrix = Mat4::makeLookAt(m_eye[0], m_eye[1], m_eyeZ, center[0], m_eye[1] + m_lookZ, center[1], upDir[0], upDir[1], upDir[2]); 256 | } 257 | 258 | inline void setEyeXZ(const Vec2f& v) 259 | { 260 | m_eye[0] = v[0]; 261 | m_eyeZ = v[1]; 262 | } 263 | 264 | inline void setEyeY(float y) 265 | { 266 | m_eye[1] = y; 267 | } 268 | 269 | //注意, 这里设置的是观察方向, 不可为0 270 | inline void setLookdirXZ(const Vec2f& v) 271 | { 272 | assert(v[0] || v[1]); 273 | m_lookDir = v * (m_dirLen / v.length()); 274 | } 275 | 276 | inline void setLookdirY(float z) 277 | { 278 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 279 | m_lookZ = CGE_MID(z, -lookUpMax, lookUpMax); 280 | } 281 | 282 | //同上, 场景漫游中, 不允许朝"正"上方观看(仰头无法形成平角 283 | inline void setLookdir(const Vec3f& v) 284 | { 285 | assert(v[0] || v[2]); 286 | m_lookDir[0] = v[0]; 287 | m_lookDir[1] = v[2]; 288 | m_lookDir.normalize(); 289 | m_lookDir *= m_dirLen; 290 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 291 | m_lookZ = CGE_MID(v[1], -lookUpMax, lookUpMax); 292 | } 293 | 294 | //转动视角, rad(弧度) > 0 时 为向右方向 295 | inline void turn(float rad) 296 | { 297 | m_lookDir = Mat2::makeRotation(rad) * m_lookDir; 298 | } 299 | 300 | //转动视角, rad(弧度) > 0 时 为右边。 301 | inline void turnTo(float rad) 302 | { 303 | m_lookDir = Vec2f(sinf(rad), cosf(rad)) * m_dirLen; 304 | } 305 | 306 | //向上观察, motion计算关系 307 | //向上观察弧度计算公式为: arctan(tan("当前向上弧度") + motion) - "当前向上弧度" 308 | inline void lookUp(float motion) 309 | { 310 | const float lookUpMax = m_dirLen * 3.732f; // tan(PI / 75); 311 | m_lookZ = CGE_MID(m_lookZ + motion * m_dirLen, -lookUpMax, lookUpMax); 312 | } 313 | 314 | //向上观察到(弧度), 直接仰视到所看弧度 315 | //范围[-PI/2.4, PI/2.4], 约正负75度角 316 | inline void lookUpTo(float rad) 317 | { 318 | m_lookZ = tanf(CGE_MID(rad, -M_PI / 2.4f, M_PI / 2.4f)) * m_dirLen; 319 | } 320 | 321 | inline void goForward(float motion) 322 | { 323 | m_eye += m_lookDir * (motion / m_dirLen); 324 | } 325 | 326 | inline void goBack(float motion) 327 | { 328 | m_eye -= m_lookDir * (motion / m_dirLen); 329 | } 330 | 331 | inline void goLeft(float motion) 332 | { 333 | float m = motion / m_dirLen; 334 | m_eye[0] -= m_lookDir[1] * m; 335 | m_eye[1] += m_lookDir[0] * m; 336 | } 337 | 338 | inline void goRight(float motion) 339 | { 340 | float m = motion / m_dirLen; 341 | m_eye[0] += m_lookDir[1] * m; 342 | m_eye[1] -= m_lookDir[0] * m; 343 | } 344 | }; 345 | } 346 | 347 | #endif -------------------------------------------------------------------------------- /demo-Teapot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: wysaid 3 | * Mail: admin@wysaid.org 4 | * Blog: http://blog.wysaid.org 5 | */ 6 | 7 | #include "cgeMat.h" 8 | #include "cgeVec.h" 9 | #include "graphics.h" 10 | #include "teapot.h" 11 | 12 | #include 13 | #include 14 | 15 | using namespace CGE; 16 | 17 | #define USE_DEPTH_TEST 0 //Not available, must be 0. 18 | 19 | //Change them as you like 20 | #define USE_PERSPECTIVE_PROJ 1 21 | #define RENDER_TRIANGLE_HALF_1 1 22 | #define RENDER_TRIANGLE_HALF_2 0 23 | 24 | #define USE_CULL_FACE_BACK 1 25 | #define USE_CULL_FACE_FRONT 0 26 | 27 | #define SCREEN_WIDTH 800 28 | #define SCREEN_HEIGHT 600 29 | 30 | #if USE_DEPTH_TEST 31 | //depth 还存在一点问题, 没有效果 32 | unsigned char g_depthMask[SCREEN_WIDTH][SCREEN_HEIGHT]; 33 | const int g_maskSize = sizeof(g_depthMask); 34 | 35 | #endif 36 | 37 | color_t g_color; 38 | 39 | template 40 | class Triangle 41 | { 42 | public: 43 | 44 | static inline void fillTriangle(const Type& v0, const Type& v1, const Type& v2) 45 | { 46 | if(v0[1] == v2[1]) 47 | { 48 | _fillSimpleTriangle(v0, v1, v2); 49 | } 50 | else if(v1[1] == v2[1]) 51 | { 52 | _fillSimpleTriangle(v1, v0, v2); 53 | } 54 | else if(v0[1] == v1[1]) 55 | { 56 | _fillSimpleTriangle(v0, v2, v1); 57 | } 58 | else 59 | { 60 | _fillNormalTriangle(v0, v1, v2); 61 | } 62 | } 63 | 64 | private: 65 | 66 | #if USE_DEPTH_TEST 67 | 68 | static inline void drawPixel(int x, int y, int depth, color_t color) 69 | { 70 | if(x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) 71 | return; 72 | 73 | if(depth >=0 && depth < 256 && g_depthMask[x][y] <= depth) 74 | { 75 | putpixel_f(x, y, color); 76 | g_depthMask[x][y] = depth; 77 | } 78 | } 79 | 80 | static inline void drawLineL2R(int x0, int depth0, int x1, int depth1, int y, color_t color) 81 | { 82 | if(x0 == x1) 83 | { 84 | drawPixel(x0, y, depth0, color); 85 | return; 86 | } 87 | 88 | int left, right; 89 | int depthL, depthR; 90 | 91 | if(x0 < x1) 92 | { 93 | left = x0; 94 | right = x1; 95 | depthL = depth0; 96 | depthR = depth1; 97 | } 98 | else 99 | { 100 | left = x1; 101 | right = x0; 102 | depthL = depth1; 103 | depthR = depth0; 104 | } 105 | 106 | float delta = float(depthR - depthL) / (right - left); 107 | for(int i = left; i <= right; ++i) 108 | { 109 | drawPixel(i, y, depthL, color); 110 | depthL += delta; 111 | } 112 | } 113 | 114 | #endif 115 | 116 | // 平顶/平底三角形, v0[1] == v2[1], v1[1] 最大 117 | static inline void _fillSimpleTriangle(const Type& v0, const Type& v1, const Type& v2) 118 | { 119 | assert(v0[1] == v2[1]); 120 | float h = v1[1] - v0[1]; 121 | 122 | float dL = (v1[0] - v0[0]) / h; 123 | float dR = (v1[0] - v2[0]) / h; 124 | 125 | float xL = v0[0], xR = v2[0]; 126 | 127 | #if USE_DEPTH_TEST 128 | 129 | static_assert(Type::VEC_DIM >= 3, "Depth-Test is not available now!"); 130 | 131 | float dDepthL = (v1[2] - v0[2]) / h; 132 | float dDepthR = (v1[2] - v2[2]) / h; 133 | float depthL = v0[2], depthR = v2[2]; 134 | 135 | #endif 136 | 137 | if(v0[1] < v1[1]) 138 | { 139 | #if RENDER_TRIANGLE_HALF_1 140 | 141 | for(int i = v0[1]; i <= v1[1]; ++i) 142 | { 143 | #if USE_DEPTH_TEST 144 | drawLineL2R(xL, depthL, xR, depthR, i, RED); 145 | 146 | depthL += dDepthL; 147 | depthR += dDepthR; 148 | #else 149 | line(xL, i, xR, i); //A Simple Function That Just Draw A Line 150 | #endif //USE_DEPTH_TEST 151 | 152 | xL += dL; 153 | xR += dR; 154 | } 155 | #endif //RENDER_TRIANGLE_HALF_1 156 | } 157 | else 158 | { 159 | #if RENDER_TRIANGLE_HALF_2 160 | 161 | for(int i = v0[1]; i >= v1[1]; --i) 162 | { 163 | #if USE_DEPTH_TEST 164 | drawLineL2R(xL, depthL, xR, depthR, i, YELLOW); 165 | depthL -= dDepthL; 166 | depthR -= dDepthR; 167 | #else 168 | line(xL, i, xR, i); //A Simple Function That Just Draw A Line 169 | #endif //USE_DEPTH_TEST 170 | 171 | xL -= dL; 172 | xR -= dR; 173 | } 174 | 175 | #endif 176 | } 177 | } 178 | 179 | 180 | static inline void _fillNormalTriangle(const Type& v0, const Type& v1, const Type& v2) 181 | { 182 | const Type *pnts[] = {&v0, &v1, &v2}; 183 | 184 | if((*pnts[0])[1] > (*pnts[1])[1]) 185 | std::swap(pnts[0], pnts[1]); 186 | 187 | if((*pnts[0])[1] > (*pnts[2])[1]) 188 | std::swap(pnts[0], pnts[2]); 189 | 190 | if((*pnts[1])[1] > (*pnts[2])[1]) 191 | std::swap(pnts[1], pnts[2]); 192 | 193 | const Type &vv0 = *pnts[0], &vv1 = *pnts[1], &vv2 = *pnts[2]; 194 | Type newPoint(vv1); 195 | 196 | newPoint[0] = vv0[0] + (vv2[0] - vv0[0]) * (vv1[1] - vv0[1]) / (vv2[1] - vv0[1]); 197 | 198 | _fillSimpleTriangle(newPoint, vv0, vv1); 199 | _fillSimpleTriangle(newPoint, vv2, vv1); 200 | } 201 | }; 202 | 203 | class Object3d 204 | { 205 | public: 206 | Object3d() 207 | { 208 | //改变 USE_PERSPECTIVE_PROJ 的值可以切换两种视图 209 | #if USE_PERSPECTIVE_PROJ 210 | m_matProj = Mat4::makePerspective(M_PI / 4.0f, 4.0f / 3.0f, 1.0f, 1000.0f); 211 | m_matModelView = Mat4::makeLookAt(0.0f, 0.0f, 800.0f, 0.0f, 0.0f, -1000.0f, 0.0f, 1.0f, 0.0f); 212 | #else 213 | m_matProj = Mat4::makeOrtho(-400.0f, 400.0f, -300.0f, 300.0f, -300.0f, 300.0f); 214 | m_matModelView.loadIdentity(); 215 | #endif 216 | } 217 | ~Object3d() {} 218 | 219 | void render(float x, float y) 220 | { 221 | m_winCoords.resize(m_vecPositions.size()); 222 | const Mat4 mvp = m_matProj * m_matModelView; 223 | const Vec4f viewPort(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT); 224 | auto iter = m_winCoords.begin(); 225 | 226 | for(auto& t : m_vecPositions) 227 | { 228 | Vec2f coord; 229 | Mat4::projectM4f(t, mvp, viewPort, coord); 230 | *iter++ = coord; 231 | } 232 | 233 | for(int i = 0; i < g_teapotIndicesNum; i += 3) 234 | { 235 | const int index1 = g_teapotIndices[i]; 236 | const int index2 = g_teapotIndices[i + 1]; 237 | const int index3 = g_teapotIndices[i + 2]; 238 | 239 | const Vec2i posPoints[] = { 240 | Vec2i(x + m_winCoords[index1][0], y + m_winCoords[index1][1]),// vec[index1][2] * 255.0f), 241 | Vec2i(x + m_winCoords[index2][0], y + m_winCoords[index2][1]),// vec[index2][2] * 255.0f), 242 | Vec2i(x + m_winCoords[index3][0], y + m_winCoords[index3][1]) // vec[index3][2] * 255.0f) 243 | }; 244 | 245 | //设置是否进行面剔除 246 | #if USE_CULL_FACE_BACK || USE_CULL_FACE_FRONT 247 | 248 | float ax = posPoints[1][0] - posPoints[0][0]; 249 | float ay = posPoints[1][1] - posPoints[0][1]; 250 | float bx = posPoints[2][0] - posPoints[1][0]; 251 | float by = posPoints[2][1] - posPoints[1][1]; 252 | float zNorm = ax * by - ay * bx; 253 | #if USE_CULL_FACE_BACK 254 | if(zNorm <= 0.0f) 255 | { 256 | goto Render_Wire_Frame; 257 | //continue; 258 | } 259 | #endif 260 | #if USE_CULL_FACE_FRONT 261 | if(zNorm > 0.0f) 262 | { 263 | goto Render_Wire_Frame; 264 | //continue; 265 | } 266 | #endif 267 | 268 | #endif 269 | 270 | //设置是否显示模拟填充 271 | #if RENDER_TRIANGLE_HALF_1 || RENDER_TRIANGLE_HALF_2 272 | 273 | setcolor(g_color ^ 0xffffff); 274 | #if USE_DEPTH_TEST 275 | memset(g_depthMask, 0, g_maskSize); 276 | #endif //USE_DEPTH_TEST 277 | Triangle::fillTriangle(posPoints[0], posPoints[1], posPoints[2]); 278 | 279 | #endif //RENDER_TRIANGLE_HALF_1 || RENDER_TRIANGLE_HALF_2 280 | 281 | Render_Wire_Frame: 282 | 283 | setcolor(g_color); 284 | line(posPoints[0][0], posPoints[0][1], posPoints[1][0], posPoints[1][1]); 285 | line(posPoints[1][0], posPoints[1][1], posPoints[2][0], posPoints[2][1]); 286 | line(posPoints[2][0], posPoints[2][1], posPoints[0][0], posPoints[0][1]); 287 | } 288 | 289 | } 290 | 291 | void pushPoint(Vec3f pnt) 292 | { 293 | m_vecPositions.push_back(pnt); 294 | } 295 | 296 | void pushPoints(Vec3f* pnt, int n) 297 | { 298 | for(int i = 0; i != n; ++i) 299 | { 300 | m_vecPositions.push_back(pnt[i]); 301 | } 302 | } 303 | 304 | void pushPoint(float x, float y, float z) 305 | { 306 | m_vecPositions.push_back(Vec3f(x, y, z)); 307 | } 308 | 309 | void rotate(float rad, float x, float y, float z) 310 | { 311 | m_matModelView.rotate(rad, x, y, z); 312 | } 313 | 314 | void rotateX(float rad) 315 | { 316 | m_matModelView.rotateX(rad); 317 | } 318 | 319 | void rotateY(float rad) 320 | { 321 | m_matModelView.rotateY(rad); 322 | } 323 | 324 | void rotateZ(float rad) 325 | { 326 | m_matModelView.rotateZ(rad); 327 | } 328 | 329 | void translateZ(float z) 330 | { 331 | m_matModelView.translateZ(z); 332 | } 333 | 334 | void clear() { m_vecPositions.clear(); } 335 | 336 | std::vector& getPositions() { return m_vecPositions; } 337 | std::vector& getIndices() { return m_vecIndices; } 338 | 339 | private: 340 | std::vector m_vecPositions; 341 | std::vector m_vecIndices; 342 | Mat4 m_matProj, m_matModelView; 343 | 344 | std::vector m_winCoords; 345 | }; 346 | 347 | 348 | bool mouseFunc(Object3d& obj) 349 | { 350 | if(!mousemsg()) return false; 351 | do 352 | { 353 | static int s_lastX, s_lastY; 354 | static int s_bIsDown = false; 355 | mouse_msg msg = getmouse(); 356 | switch (msg.msg) 357 | { 358 | case mouse_msg_down: 359 | s_lastX = msg.x; 360 | s_lastY = msg.y; 361 | s_bIsDown = true; 362 | break; 363 | case mouse_msg_up: 364 | s_bIsDown = false; 365 | break; 366 | case mouse_msg_wheel: 367 | obj.translateZ(msg.wheel / 12.0f); 368 | break; 369 | default: 370 | break; 371 | } 372 | 373 | if(s_bIsDown && msg.is_move()) 374 | { 375 | obj.rotateX((msg.y - s_lastY) / 100.0f); 376 | obj.rotateY((msg.x - s_lastX) / 100.0f); 377 | s_lastX = msg.x; 378 | s_lastY = msg.y; 379 | } 380 | }while(mousemsg()); 381 | return true; 382 | } 383 | 384 | void genTeapot(Object3d& obj, float scale) 385 | { 386 | auto& pos = obj.getPositions(); 387 | auto& indices = obj.getIndices(); 388 | 389 | pos.clear(); 390 | pos.reserve(g_teapotIndicesNum / 3); 391 | 392 | for(int i = 0; i < g_teapotPositionNum; i += 3) 393 | { 394 | pos.push_back(Vec3f(g_teapotPositions[i] * scale, g_teapotPositions[i + 1] * scale, g_teapotPositions[i + 2] * scale)); 395 | } 396 | 397 | indices.clear(); 398 | indices.assign(g_teapotIndices, g_teapotIndices + g_teapotIndicesNum); 399 | } 400 | 401 | int main() 402 | { 403 | initgraph(SCREEN_WIDTH, SCREEN_HEIGHT, INIT_RENDERMANUAL); 404 | 405 | Object3d obj; 406 | randomize(); 407 | 408 | genTeapot(obj, 10.0f); 409 | 410 | int i = 0; 411 | static bool s_useBlur = false; 412 | float x = 0.0f, y = 0.0f; 413 | float dx = randomf()* 5.0f + 1.0f, dy = randomf()* 5.0f + 1.0f; 414 | float radX = randomf()*10.0f + 0.001f, radY = randomf() * 10.0f, radZ = randomf() * 10.0f; 415 | setbkmode(TRANSPARENT); 416 | setfillcolor(DARKGRAY); 417 | for(; is_run(); delay_fps(60)) 418 | { 419 | if(s_useBlur) imagefilter_blurring(0, 0x79, 0x100); 420 | else cleardevice(); 421 | mouseFunc(obj); 422 | 423 | obj.render(0, 0); 424 | 425 | g_color = HSVtoRGB(i*2, 1.0f, 1.0f); 426 | outtextxy(20, 10, "点击空格键启用模糊滤镜, 鼠标滚轮移动模型Z值, enter键截屏"); 427 | 428 | x += dx; 429 | y += dy; 430 | 431 | if(x < 0.0f || x > 800.0f) 432 | { 433 | dx = -dx; 434 | x += dx; 435 | } 436 | if(y < 0.0f || y > 600.0f) 437 | { 438 | dy = -dy; 439 | y += dy; 440 | } 441 | 442 | ++i %= 360; 443 | 444 | if(kbhit()) 445 | { 446 | switch (getch()) 447 | { 448 | case ' ': 449 | s_useBlur = !s_useBlur; 450 | break; 451 | case '\r':case '\n': 452 | { 453 | saveimage(NULL, "screen_shot.bmp"); 454 | } 455 | break; 456 | default: 457 | break; 458 | } 459 | flushkey(); 460 | } 461 | } 462 | closegraph(); 463 | return 0; 464 | } -------------------------------------------------------------------------------- /demo-SceneRoaming.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: wysaid 3 | * Mail: admin@wysaid.org 4 | * Blog: http://blog.wysaid.org 5 | */ 6 | 7 | #define SHOW_CONSOLE 8 | #define _CRT_SECURE_NO_WARNINGS 9 | #include "cgeScene.h" 10 | #include "cgeMat.h" 11 | #include "graphics.h" 12 | #include 13 | 14 | using namespace CGE; 15 | using namespace std; 16 | 17 | #define SCREEN_WIDTH 800 18 | #define SCREEN_HEIGHT 600 19 | 20 | #define CREATE_FUNC(className) static inline className* create(){ return new className;} 21 | 22 | template 23 | static inline void line(T p1, T p2) 24 | { 25 | //3d坐标系与窗口坐标系y方向相反 26 | //使用 height - y 来修正. 27 | line(p1[0], SCREEN_HEIGHT - p1[1], p2[0], SCREEN_HEIGHT - p2[1]); 28 | } 29 | 30 | class Object3d 31 | { 32 | protected: 33 | //避免大量拷贝带来开销, 不允许直接创建实例, 只能通过create方法创建指针. 34 | Object3d() : m_matrix(Mat4::makeIdentity()) {} 35 | public: 36 | ~Object3d() {} 37 | 38 | CREATE_FUNC(Object3d) 39 | 40 | virtual void render(const Mat4& mvp, const Vec4f& viewPort) 41 | { 42 | m_winCoords.resize(m_vecPositions.size()); 43 | auto winIter = m_winCoords.begin(); 44 | memset(m_winCoords.data(), 0xff, m_winCoords.size() * sizeof(m_winCoords[0])); 45 | 46 | const Mat4& m = mvp * m_matrix; 47 | 48 | for (auto& pos : m_vecPositions) 49 | { 50 | Mat4::projectM4f(pos, m, viewPort, *winIter++); 51 | } 52 | 53 | for(int i = 1; i < m_vecIndices.size(); i += 2) 54 | { 55 | auto& p0 = m_winCoords[m_vecIndices[i - 1]]; 56 | auto& p1 = m_winCoords[m_vecIndices[i]]; 57 | 58 | if ((unsigned&)p0[0] != 0xffffffff && (unsigned&)p1[0] != 0xffffffff) 59 | { 60 | line(p0, p1); 61 | } 62 | } 63 | 64 | } 65 | 66 | virtual int objType() { return -1; } 67 | 68 | inline vector& positions() { return m_vecPositions; } 69 | inline const vector& positions() const { return m_vecPositions; } 70 | 71 | inline vector& indices() { return m_vecIndices; } 72 | inline const vector& indices() const { return m_vecIndices; } 73 | 74 | inline Mat4& matrix() { return m_matrix; } 75 | inline const Mat4& matrix() const { return m_matrix; } 76 | 77 | protected: 78 | vector m_vecPositions; 79 | vector m_vecIndices; 80 | mutable vector m_winCoords; //A cache for rendering. 81 | Mat4 m_matrix; 82 | }; 83 | 84 | //使用xOz平面进行漫游, y方向朝上. 85 | class Scene : public SceneInterface 86 | { 87 | public: 88 | 89 | Scene(float w, float h) : SceneInterface(w, h) 90 | { 91 | } 92 | 93 | ~Scene() 94 | { 95 | for (auto* p : m_vecObjects) 96 | { 97 | delete p; 98 | } 99 | 100 | m_vecObjects.clear(); 101 | } 102 | 103 | void render(const Vec4f& viewPort) 104 | { 105 | const Mat4& mvp = m_projectionMatrix * m_modelViewMatrix; 106 | 107 | for (auto* v : m_vecObjects) 108 | { 109 | v->render(mvp, viewPort); 110 | } 111 | } 112 | 113 | void addObject(Object3d* obj) 114 | { 115 | m_vecObjects.push_back(obj); 116 | } 117 | 118 | private: 119 | vector m_vecObjects; 120 | }; 121 | 122 | ////////////////////////////////////////////////////////////////////////// 123 | 124 | //Special deal. 125 | class Mesh : public Object3d 126 | { 127 | public: 128 | static inline Mesh* create(int w, int h) 129 | { 130 | assert(w > 0 && h > 0); //宽高必须大于0 131 | 132 | Mesh* m = new Mesh; 133 | m->m_width = w + 1; 134 | m->m_height = h + 1; 135 | auto& positions = m->positions(); 136 | int total = m->m_width * m->m_height; 137 | 138 | positions.reserve(total); 139 | 140 | for (int i = 0; i <= h; ++i) 141 | { 142 | for (int j = 0; j <= w; ++j) 143 | { 144 | positions.push_back(Vec3f(j / (float)w - 0.5f, i / (float)h - 0.5f, 0.0f)); 145 | } 146 | } 147 | 148 | return m; 149 | } 150 | 151 | int objType() { return 0; } //0 for mesh. 152 | 153 | virtual void render(const Mat4& mvp, const Vec4f& viewPort) 154 | { 155 | setcolor(0); 156 | m_winCoords.resize(m_vecPositions.size()); 157 | auto winIter = m_winCoords.begin(); 158 | memset(m_winCoords.data(), 0xff, m_winCoords.size() * sizeof(m_winCoords[0])); 159 | 160 | const Mat4& m = mvp * m_matrix; 161 | 162 | for (auto& pos : m_vecPositions) 163 | { 164 | Mat4::projectM4f(pos, m, viewPort, *winIter++); 165 | } 166 | 167 | const int w = m_width - 1; 168 | const int h = m_height - 1; 169 | 170 | for (int i = 0; i != h; ++i) 171 | { 172 | const int k = i + 1; 173 | const int thisLine = i * m_width; 174 | const int nextLine = k * m_width; 175 | 176 | for (int j = 0; j != w; ++j) 177 | { 178 | const int thisLineIndex = thisLine + j; 179 | const int nextLineIndex = nextLine + j; 180 | const auto& v1 = m_winCoords[thisLineIndex]; 181 | const auto& v2 = m_winCoords[thisLineIndex + 1]; 182 | const auto& v3 = m_winCoords[nextLineIndex + 1]; 183 | const auto& v4 = m_winCoords[nextLineIndex]; 184 | 185 | #define TRANS_VEC2I_TYPE(v) Vec2i(v[0], v[1]) 186 | 187 | //逆时针方向绘制 188 | const Vec2i pnts[4] = { 189 | TRANS_VEC2I_TYPE(v1), 190 | TRANS_VEC2I_TYPE(v2), 191 | TRANS_VEC2I_TYPE(v3), 192 | TRANS_VEC2I_TYPE(v4) 193 | }; 194 | 195 | //Clip for perspective projection. 196 | if ((unsigned&)v1[0] != 0xffffffff && (unsigned&)v2[0] != 0xffffffff 197 | && (unsigned&)v3[0] != 0xffffffff && (unsigned&)v4[0] != 0xffffffff) 198 | { 199 | // fillpoly(4, &pnts[0][0]); //填充矩形区域 200 | // drawpoly(4, &pnts[0][0]); 201 | 202 | line(pnts[0], pnts[1]); 203 | line(pnts[1], pnts[2]); 204 | line(pnts[2], pnts[3]); 205 | line(pnts[3], pnts[0]); 206 | } 207 | } 208 | } 209 | } 210 | 211 | protected: 212 | 213 | int m_width, m_height; 214 | }; 215 | 216 | class Ball : public Object3d 217 | { 218 | Ball(int lats, int height) : m_lats(lats), m_height(height), m_rot(0.0f) {} 219 | public: 220 | static inline Ball* create(float radius, int lats, int height, const Vec3f& transform) 221 | { 222 | auto* ball = new Ball(lats, height); 223 | assert(radius > 0.0f); 224 | auto& pos = ball->positions(); 225 | auto& indices = ball->indices(); 226 | pos.reserve(lats * height); 227 | indices.reserve(pos.size() * 2); 228 | 229 | for (int i = 0; i <= lats; ++i) 230 | { 231 | for (int j = 0; j <= height; ++j) 232 | { 233 | float theta = i * M_PI / lats; 234 | float phi = j * 2.0f * M_PI / height; 235 | float sinTheta = sinf(theta); 236 | float sinPhi = sinf(phi); 237 | float cosTheta = cosf(theta); 238 | float cosPhi = cosf(phi); 239 | 240 | float x = cosPhi * sinTheta; 241 | float y = cosTheta; 242 | float z = sinPhi * sinTheta; 243 | 244 | pos.push_back(Vec3f(x, y, z) * radius + transform); 245 | } 246 | } 247 | 248 | for (int i = 0; i != lats; ++i) 249 | { 250 | int thisLine = i * (height + 1); 251 | for (int j = 0; j != height; ++j) 252 | { 253 | int first = thisLine + j; 254 | int second = first + height + 1; 255 | 256 | indices.push_back(first); 257 | indices.push_back(first + 1); 258 | 259 | indices.push_back(first + 1); 260 | indices.push_back(second + 1); 261 | 262 | indices.push_back(second + 1); 263 | indices.push_back(second); 264 | 265 | indices.push_back(second); 266 | indices.push_back(first); 267 | } 268 | } 269 | 270 | return ball; 271 | } 272 | 273 | int objType() { return 1; } 274 | 275 | void render(const Mat4& mvp, const Vec4f& viewPort) 276 | { 277 | setcolor(0x333366); 278 | m_matrix = Mat4::makeTranslation(0.0f, 0.0f, 350.0f) * Mat4::makeXRotation(M_PI * 0.5f) * Mat4::makeYRotation(m_rot += 0.02f); 279 | Object3d::render(mvp, viewPort); 280 | } 281 | 282 | private: 283 | int m_lats, m_height; 284 | float m_rot; 285 | }; 286 | 287 | Mesh* getMesh(int w, int h, const Vec3f& rot, const Vec3f& scaling, const Vec3f& transform) 288 | { 289 | Mesh* m = Mesh::create(w, h); 290 | auto& matrix = m->matrix(); 291 | 292 | matrix = Mat4::makeTranslation(transform[0], transform[1], transform[2]) * 293 | Mat4::makeXRotation(rot[0]) * Mat4::makeYRotation(rot[1]) * Mat4::makeZRotation(rot[2]) * 294 | Mat4::makeScale(scaling[0], scaling[1], scaling[2]); 295 | 296 | return m; 297 | } 298 | 299 | void initScene(Scene& s) 300 | { 301 | //地面 302 | Mesh* m = getMesh(16, 16, Vec3f(0.0f, 0.0f, 0.0f), Vec3f(2000.0f, 2000.0f, 2000.0f), Vec3f(0.0f, 0.0f, 0.0f)); 303 | s.addObject(m); 304 | 305 | //前面墙 306 | m = getMesh(16, 4, Vec3f((float)M_PI / 2.0f, 0.0f, 0.0f), Vec3f(2000.0f, 500.0f, 2000.0f), Vec3f(0.0f, -1000.0f, 250.0f)); 307 | s.addObject(m); 308 | 309 | //后面墙 310 | m = getMesh(16, 4, Vec3f((float)M_PI / 2.0f, 0.0f, 0.0f), Vec3f(2000.0f, 500.0f, 2000.0f), Vec3f(0.0f, 1000.0f, 250.0f)); 311 | s.addObject(m); 312 | 313 | //左侧墙 314 | m = getMesh(4, 16, Vec3f(0.0f, (float)M_PI / 2.0f, 0.0f), Vec3f(500.0f, 2000.0f, 2000.0f), Vec3f(1000.0f, 0.0f, 250.0f)); 315 | s.addObject(m); 316 | 317 | //右侧墙 318 | m = getMesh(4, 16, Vec3f(0.0f, (float)M_PI / 2.0f, 0.0f), Vec3f(500.0f, 2000.0f, 2000.0f), Vec3f(-1000.0f, 0.0f, 250.0f)); 319 | s.addObject(m); 320 | 321 | //天花板 322 | // m = getMesh(16, 16, Vec3f(0.0f, 0.0f, 0.0f), Vec3f(2000.0f, 2000.0f, 2000.0f), Vec3f(0.0f, 0.0f, 500.0f)); 323 | // s.addObject(m); 324 | 325 | Ball* ball = Ball::create(200.0f, 10, 10, Vec3f(0.0f, 0.0f, 0.0f)); 326 | s.addObject(ball); 327 | } 328 | 329 | int main() 330 | { 331 | initgraph(SCREEN_WIDTH, SCREEN_HEIGHT, INIT_RENDERMANUAL); 332 | setcaption("Soft Scene Roaming by wysaid."); 333 | setbkmode(TRANSPARENT); 334 | setfillcolor(0xaaaaaa); 335 | 336 | Scene scene(SCREEN_WIDTH, SCREEN_HEIGHT); 337 | 338 | initScene(scene); 339 | 340 | const Vec4f viewPort(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT); 341 | const float motion = 5.0f; 342 | const float standupHeight = 120.0f; //地板高度为0, 人站立眼睛高度120 343 | float jumpSpeed = 0.0f; //跳起速度 344 | float gravityAccSpeed = -0.3f; //重力加速度 345 | char textBuffer[1024]; 346 | 347 | scene.setEyeXY(Vec2f(0.0f, 500.0f)); 348 | scene.setEyeZ(standupHeight); // 站立观察高度 349 | scene.setLookdirXY(Vec2f(0.0f, -1000.0f)); 350 | scene.updatePerspective(); 351 | scene.updateView(); 352 | 353 | for (; is_run(); delay_fps(60)) 354 | { 355 | bar(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); 356 | setcolor(0); 357 | 358 | if (keystate('A') || keystate(key_left)) 359 | scene.goLeft(motion); 360 | else if (keystate('D') || keystate(key_right)) 361 | scene.goRight(motion); 362 | 363 | if (keystate('W') || keystate(key_up)) 364 | scene.goForward(motion); 365 | else if (keystate('S') || keystate(key_down)) 366 | scene.goBack(motion); 367 | 368 | auto& eye = scene.eyeXY(); 369 | if (eye[0] < -900.0f) eye[0] = -900.0f; 370 | if (eye[0] > 900.0f) eye[0] = 900.0f; 371 | if (eye[1] < -900.0f) eye[1] = -900.0f; 372 | if (eye[1] > 900.0f) eye[1] = 900.0f; 373 | 374 | static bool isJumping = false; 375 | 376 | if (isJumping) 377 | { 378 | scene.setEyeZ(scene.eyeZ() + jumpSpeed); 379 | jumpSpeed += gravityAccSpeed; 380 | if (scene.eyeZ() < standupHeight) 381 | { 382 | scene.setEyeZ(standupHeight); 383 | isJumping = false; 384 | } 385 | } 386 | 387 | while (kbhit()) 388 | { 389 | int key = getch(); 390 | 391 | if (!isJumping && key == key_space) 392 | { 393 | isJumping = true; 394 | jumpSpeed = 12.0f; 395 | } 396 | } 397 | 398 | while (mousemsg()) 399 | { 400 | static bool isMouseDown = false; 401 | static Vec2f lastMousePos; 402 | mouse_msg msg = getmouse(); 403 | 404 | switch (msg.msg) 405 | { 406 | case mouse_msg_down: 407 | lastMousePos[0] = msg.x; 408 | lastMousePos[1] = msg.y; 409 | isMouseDown = true; 410 | break; 411 | case mouse_msg_up: 412 | isMouseDown = false; 413 | break; 414 | case mouse_msg_move: 415 | if (isMouseDown) 416 | { 417 | Vec2f curr(msg.x, msg.y); 418 | Vec2f delta = curr - lastMousePos; 419 | scene.turn(delta[0] / 600.0f); 420 | scene.lookUp(delta[1] / 600.0f); 421 | lastMousePos = curr; 422 | } 423 | break; 424 | case mouse_msg_wheel: 425 | scene.lookIn(msg.wheel / 2000.0f); 426 | scene.updatePerspective(); 427 | break; 428 | default: 429 | break; 430 | } 431 | 432 | } 433 | 434 | scene.updateView(); 435 | scene.render(viewPort); 436 | 437 | static unsigned int frameCount = 0; 438 | if(frameCount % 6 == 0) 439 | sprintf(textBuffer, "使用方向键控制视点移动, 鼠标按住不放拖动视角\n空格键跳跃, 鼠标滚轮调节视景区\neye: %g, %g\nheight: %g\nlook dir: %g, %g", eye[0], eye[1], scene.eyeZ(), scene.lookDirXY()[0], scene.lookDirXY()[1]); 440 | 441 | ++frameCount; 442 | setcolor(0x773333); 443 | outtextrect(20, 20, 500, 200, textBuffer); 444 | } 445 | 446 | closegraph(); 447 | return 0; 448 | } -------------------------------------------------------------------------------- /algorithm/cgeVec.h: -------------------------------------------------------------------------------- 1 | /* 2 | @Author: wysaid 3 | @Blog: blog.wysaid.org 4 | @Date: 2013-10-31 5 | @Description: Provide some cpu math algorithms like glsl shaders. 6 | */ 7 | 8 | #ifndef _CGE_VEC_H_ 9 | #define _CGE_VEC_H_ 10 | 11 | #include 12 | #include "cgeStaticAssert.h" 13 | 14 | #ifndef CGE_CLAMP 15 | 16 | #define CGE_CLAMP(n, low, high) do{\ 17 | if(n < low) n = low;\ 18 | else if(n > high) n = high;\ 19 | }while(0)\ 20 | 21 | #endif 22 | 23 | namespace CGE 24 | { 25 | //Only for class Vec. 26 | template 27 | struct VecAlgorithmHelp; //Check your code, when this is called. 28 | 29 | template 30 | struct VecAlgorithmHelp 31 | { 32 | static inline V _plus(const V& v1, const V& v2) 33 | { 34 | return V(v1[0] + v2[0]); 35 | } 36 | 37 | static inline V _minus(const V& v1, const V& v2) 38 | { 39 | return V(v1[0] - v2[0]); 40 | } 41 | 42 | static inline V _times(const V& v1, const V& v2) 43 | { 44 | return V(v1[0] * v2[0]); 45 | } 46 | 47 | static inline V _divide(const V& v1, const V& v2) 48 | { 49 | return V(v1[0] / v2[0]); 50 | } 51 | 52 | static inline V& _inc(V& v1, const V& v2) 53 | { 54 | v1[0] += v2[0]; 55 | return v1; 56 | } 57 | 58 | static inline V& _sub(V& v1, const V& v2) 59 | { 60 | v1[0] -= v2[0]; 61 | return v1; 62 | } 63 | 64 | static inline V& _mul(V& v1, const V& v2) 65 | { 66 | v1[0] *= v2[0]; 67 | return v1; 68 | } 69 | 70 | static inline V& _div(V& v1, const V& v2) 71 | { 72 | v1[0] /= v2[0]; 73 | return v1; 74 | } 75 | 76 | static inline V& _assign(V& v1, const V& v2) 77 | { 78 | v1[0] = v2[0]; 79 | return v1; 80 | } 81 | 82 | ////////////////////////////////////////////////////////////////////////// 83 | 84 | static inline V _plus(const V& v1, typename V::VecDataType t) 85 | { 86 | return V(v1[0] + t); 87 | } 88 | 89 | static inline V _minus(const V& v1, typename V::VecDataType t) 90 | { 91 | return V(v1[0] - t); 92 | } 93 | 94 | static inline V _times(const V& v1, typename V::VecDataType t) 95 | { 96 | return V(v1[0] * t); 97 | } 98 | 99 | static inline V _divide(const V& v1, typename V::VecDataType t) 100 | { 101 | return V(v1[0] / t); 102 | } 103 | 104 | static inline V& _inc(V& v1, typename V::VecDataType t) 105 | { 106 | v1[0] += t; 107 | return v1; 108 | } 109 | 110 | static inline V& _sub(V& v1, typename V::VecDataType t) 111 | { 112 | v1[0] -= t; 113 | return v1; 114 | } 115 | 116 | static inline V& _mul(V& v1, typename V::VecDataType t) 117 | { 118 | v1[0] *= t; 119 | return v1; 120 | } 121 | 122 | static inline V& _div(V& v1, typename V::VecDataType t) 123 | { 124 | v1[0] /= t; 125 | return v1; 126 | } 127 | 128 | static inline V& _assign(V& v1, typename V::VecDataType t) 129 | { 130 | v1[0] = t; 131 | return v1; 132 | } 133 | 134 | static inline typename V::VecDataType _dot(const V& v1, const V& v2) 135 | { 136 | return v1[0]*v2[0]; 137 | } 138 | 139 | static inline typename V::VecDataType _dot(const V& v) 140 | { 141 | return v[0]*v[0]; 142 | } 143 | 144 | static inline float _len(const V& v) 145 | { 146 | return v[0]; 147 | } 148 | 149 | static inline V& _norm(V& v) 150 | { 151 | const float len = 1.0f / _len(v); 152 | v[0] *= len; 153 | return v; 154 | } 155 | 156 | static inline void clamp(V& v, typename V::VecDataType low, typename V::VecDataType high) 157 | { 158 | CGE_CLAMP(v[0], low, high); 159 | } 160 | }; 161 | 162 | ////////////////////////////////////////////////////////////////////////// 163 | 164 | template 165 | struct VecAlgorithmHelp 166 | { 167 | static inline V _plus(const V& v1, const V& v2) 168 | { 169 | return V(v1[0] + v2[0], v1[1] + v2[1]); 170 | } 171 | 172 | static inline V _minus(const V& v1, const V& v2) 173 | { 174 | return V(v1[0] - v2[0], v1[1] - v2[1]); 175 | } 176 | 177 | static inline V _times(const V& v1, const V& v2) 178 | { 179 | return V(v1[0] * v2[0], v1[1] * v2[1]); 180 | } 181 | 182 | static inline V _divide(const V& v1, const V& v2) 183 | { 184 | return V(v1[0] / v2[0], v1[1] / v2[1]); 185 | } 186 | 187 | static inline V& _inc(V& v1, const V& v2) 188 | { 189 | v1[0] += v2[0]; 190 | v1[1] += v2[1]; 191 | return v1; 192 | } 193 | 194 | static inline V& _sub(V& v1, const V& v2) 195 | { 196 | v1[0] -= v2[0]; 197 | v1[1] -= v2[1]; 198 | return v1; 199 | } 200 | 201 | static inline V& _mul(V& v1, const V& v2) 202 | { 203 | v1[0] *= v2[0]; 204 | v1[1] *= v2[1]; 205 | return v1; 206 | } 207 | 208 | static inline V& _div(V& v1, const V& v2) 209 | { 210 | v1[0] /= v2[0]; 211 | v1[1] /= v2[1]; 212 | return v1; 213 | } 214 | 215 | static inline V& _assign(V& v1, const V& v2) 216 | { 217 | v1[0] = v2[0]; 218 | v1[1] = v2[1]; 219 | return v1; 220 | } 221 | 222 | ////////////////////////////////////////////////////////////////////////// 223 | 224 | static inline V _plus(const V& v1, typename V::VecDataType t) 225 | { 226 | return V(v1[0] + t, v1[1] + t); 227 | } 228 | 229 | static inline V _minus(const V& v1, typename V::VecDataType t) 230 | { 231 | return V(v1[0] - t, v1[1] - t); 232 | } 233 | 234 | static inline V _times(const V& v1, typename V::VecDataType t) 235 | { 236 | return V(v1[0] * t, v1[1] * t); 237 | } 238 | 239 | static inline V _divide(const V& v1, typename V::VecDataType t) 240 | { 241 | return V(v1[0] / t, v1[1] / t); 242 | } 243 | 244 | static inline V& _inc(V& v1, typename V::VecDataType t) 245 | { 246 | v1[0] += t; 247 | v1[1] += t; 248 | return v1; 249 | } 250 | 251 | static inline V& _sub(V& v1, typename V::VecDataType t) 252 | { 253 | v1[0] -= t; 254 | v1[1] -= t; 255 | return v1; 256 | } 257 | 258 | static inline V& _mul(V& v1, typename V::VecDataType t) 259 | { 260 | v1[0] *= t; 261 | v1[1] *= t; 262 | return v1; 263 | } 264 | 265 | static inline V& _div(V& v1, typename V::VecDataType t) 266 | { 267 | v1[0] /= t; 268 | v1[1] /= t; 269 | return v1; 270 | } 271 | 272 | static inline V& _assign(V& v1, typename V::VecDataType t) 273 | { 274 | v1[0] = t; 275 | v1[1] = t; 276 | return v1; 277 | } 278 | 279 | static inline typename V::VecDataType _dot(const V& v1, const V& v2) 280 | { 281 | return v1[0]*v2[0] + v1[1]*v2[1]; 282 | } 283 | 284 | static inline typename V::VecDataType _dot(const V& v) 285 | { 286 | return v[0]*v[0] + v[1]*v[1]; 287 | } 288 | 289 | static inline float _len(const V& v) 290 | { 291 | return sqrtf(v[0]*v[0] + v[1]*v[1]); 292 | } 293 | 294 | static inline V& _norm(V& v) 295 | { 296 | const float len = 1.0f / _len(v); 297 | v[0] *= len; 298 | v[1] *= len; 299 | return v; 300 | } 301 | 302 | static inline void clamp(V& v, typename V::VecDataType low, typename V::VecDataType high) 303 | { 304 | CGE_CLAMP(v[0], low, high); 305 | CGE_CLAMP(v[1], low, high); 306 | } 307 | }; 308 | 309 | ////////////////////////////////////////////////////////////////////////// 310 | 311 | template 312 | struct VecAlgorithmHelp 313 | { 314 | static inline V _plus(const V& v1, const V& v2) 315 | { 316 | return V(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]); 317 | } 318 | 319 | static inline V _minus(const V& v1, const V& v2) 320 | { 321 | return V(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]); 322 | } 323 | 324 | static inline V _times(const V& v1, const V& v2) 325 | { 326 | return V(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]); 327 | } 328 | 329 | static inline V _divide(const V& v1, const V& v2) 330 | { 331 | return V(v1[0] / v2[0], v1[1] / v2[1], v1[2] / v2[2]); 332 | } 333 | 334 | static inline V& _inc(V& v1, const V& v2) 335 | { 336 | v1[0] += v2[0]; 337 | v1[1] += v2[1]; 338 | v1[2] += v2[2]; 339 | return v1; 340 | } 341 | 342 | static inline V& _sub(V& v1, const V& v2) 343 | { 344 | v1[0] -= v2[0]; 345 | v1[1] -= v2[1]; 346 | v1[2] -= v2[2]; 347 | return v1; 348 | } 349 | 350 | static inline V& _mul(V& v1, const V& v2) 351 | { 352 | v1[0] *= v2[0]; 353 | v1[1] *= v2[1]; 354 | v1[2] *= v2[2]; 355 | return v1; 356 | } 357 | 358 | static inline V& _div(V& v1, const V& v2) 359 | { 360 | v1[0] /= v2[0]; 361 | v1[1] /= v2[1]; 362 | v1[2] /= v2[2]; 363 | return v1; 364 | } 365 | 366 | static inline V& _assign(V& v1, const V& v2) 367 | { 368 | v1[0] = v2[0]; 369 | v1[1] = v2[1]; 370 | v1[2] = v2[2]; 371 | return v1; 372 | } 373 | 374 | ////////////////////////////////////////////////////////////////////////// 375 | 376 | static inline V _plus(const V& v1, typename V::VecDataType t) 377 | { 378 | return V(v1[0] + t, v1[1] + t, v1[2] + t); 379 | } 380 | 381 | static inline V _minus(const V& v1, typename V::VecDataType t) 382 | { 383 | return V(v1[0] - t, v1[1] - t, v1[2] - t); 384 | } 385 | 386 | static inline V _times(const V& v1, typename V::VecDataType t) 387 | { 388 | return V(v1[0] * t, v1[1] * t, v1[2] * t); 389 | } 390 | 391 | static inline V _divide(const V& v1, typename V::VecDataType t) 392 | { 393 | return V(v1[0] / t, v1[1] / t, v1[2] / t); 394 | } 395 | 396 | static inline V& _inc(V& v1, typename V::VecDataType t) 397 | { 398 | v1[0] += t; 399 | v1[1] += t; 400 | v1[2] += t; 401 | return v1; 402 | } 403 | 404 | static inline V& _sub(V& v1, typename V::VecDataType t) 405 | { 406 | v1[0] -= t; 407 | v1[1] -= t; 408 | v1[2] -= t; 409 | return v1; 410 | } 411 | 412 | static inline V& _mul(V& v1, typename V::VecDataType t) 413 | { 414 | v1[0] *= t; 415 | v1[1] *= t; 416 | v1[2] *= t; 417 | return v1; 418 | } 419 | 420 | static inline V& _div(V& v1, typename V::VecDataType t) 421 | { 422 | v1[0] /= t; 423 | v1[1] /= t; 424 | v1[2] /= t; 425 | return v1; 426 | } 427 | 428 | static inline V& _assign(V& v1, typename V::VecDataType t) 429 | { 430 | v1[0] = t; 431 | v1[1] = t; 432 | v1[2] = t; 433 | return v1; 434 | } 435 | 436 | static inline typename V::VecDataType _dot(const V& v1, const V& v2) 437 | { 438 | return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; 439 | } 440 | 441 | static inline typename V::VecDataType _dot(const V& v) 442 | { 443 | return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 444 | } 445 | 446 | static inline float _len(const V& v) 447 | { 448 | return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); 449 | } 450 | 451 | static inline V& _norm(V& v) 452 | { 453 | const float len = 1.0f / _len(v); 454 | v[0] *= len; 455 | v[1] *= len; 456 | v[2] *= len; 457 | return v; 458 | } 459 | 460 | static inline void clamp(V& v, typename V::VecDataType low, typename V::VecDataType high) 461 | { 462 | CGE_CLAMP(v[0], low, high); 463 | CGE_CLAMP(v[1], low, high); 464 | CGE_CLAMP(v[2], low, high); 465 | } 466 | }; 467 | 468 | ////////////////////////////////////////////////////////////////////////// 469 | 470 | template 471 | struct VecAlgorithmHelp 472 | { 473 | static inline V _plus(const V& v1, const V& v2) 474 | { 475 | return V(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2], v1[3] + v2[3]); 476 | } 477 | 478 | static inline V _minus(const V& v1, const V& v2) 479 | { 480 | return V(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2], v1[3] - v2[3]); 481 | } 482 | 483 | static inline V _times(const V& v1, const V& v2) 484 | { 485 | return V(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3]); 486 | } 487 | 488 | static inline V _divide(const V& v1, const V& v2) 489 | { 490 | return V(v1[0] / v2[0], v1[1] / v2[1], v1[2] / v2[2], v1[3] / v2[3]); 491 | } 492 | 493 | static inline V& _inc(V& v1, const V& v2) 494 | { 495 | v1[0] += v2[0]; 496 | v1[1] += v2[1]; 497 | v1[2] += v2[2]; 498 | v1[3] += v2[3]; 499 | return v1; 500 | } 501 | 502 | static inline V& _sub(V& v1, const V& v2) 503 | { 504 | v1[0] -= v2[0]; 505 | v1[1] -= v2[1]; 506 | v1[2] -= v2[2]; 507 | v1[3] -= v2[3]; 508 | return v1; 509 | } 510 | 511 | static inline V& _mul(V& v1, const V& v2) 512 | { 513 | v1[0] *= v2[0]; 514 | v1[1] *= v2[1]; 515 | v1[2] *= v2[2]; 516 | v1[3] *= v2[3]; 517 | return v1; 518 | } 519 | 520 | static inline V& _div(V& v1, const V& v2) 521 | { 522 | v1[0] /= v2[0]; 523 | v1[1] /= v2[1]; 524 | v1[2] /= v2[2]; 525 | v1[3] /= v2[3]; 526 | return v1; 527 | } 528 | 529 | static inline V& _assign(V& v1, const V& v2) 530 | { 531 | v1[0] = v2[0]; 532 | v1[1] = v2[1]; 533 | v1[2] = v2[2]; 534 | v1[3] = v2[3]; 535 | return v1; 536 | } 537 | 538 | ////////////////////////////////////////////////////////////////////////// 539 | 540 | static inline V _plus(const V& v1, typename V::VecDataType t) 541 | { 542 | return V(v1[0] + t, v1[1] + t, v1[2] + t, v1[3] + t); 543 | } 544 | 545 | static inline V _minus(const V& v1, typename V::VecDataType t) 546 | { 547 | return V(v1[0] - t, v1[1] - t, v1[2] - t, v1[3] - t); 548 | } 549 | 550 | static inline V _times(const V& v1, typename V::VecDataType t) 551 | { 552 | return V(v1[0] * t, v1[1] * t, v1[2] * t, v1[3] * t); 553 | } 554 | 555 | static inline V _divide(const V& v1, typename V::VecDataType t) 556 | { 557 | return V(v1[0] / t, v1[1] / t, v1[2] / t, v1[3] / t); 558 | } 559 | 560 | static inline V& _inc(V& v1, typename V::VecDataType t) 561 | { 562 | v1[0] += t; 563 | v1[1] += t; 564 | v1[2] += t; 565 | v1[3] += t; 566 | return v1; 567 | } 568 | 569 | static inline V& _sub(V& v1, typename V::VecDataType t) 570 | { 571 | v1[0] -= t; 572 | v1[1] -= t; 573 | v1[2] -= t; 574 | v1[3] -= t; 575 | return v1; 576 | } 577 | 578 | static inline V& _mul(V& v1, typename V::VecDataType t) 579 | { 580 | v1[0] *= t; 581 | v1[1] *= t; 582 | v1[2] *= t; 583 | v1[3] *= t; 584 | return v1; 585 | } 586 | 587 | static inline V& _div(V& v1, typename V::VecDataType t) 588 | { 589 | v1[0] /= t; 590 | v1[1] /= t; 591 | v1[2] /= t; 592 | v1[3] /= t; 593 | return v1; 594 | } 595 | 596 | static inline V& _assign(V& v1, typename V::VecDataType t) 597 | { 598 | v1[0] = t; 599 | v1[1] = t; 600 | v1[2] = t; 601 | v1[3] = t; 602 | return v1; 603 | } 604 | 605 | static inline typename V::VecDataType _dot(const V& v1, const V& v2) 606 | { 607 | return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; 608 | } 609 | 610 | static inline typename V::VecDataType _dot(const V& v) 611 | { 612 | return v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]; 613 | } 614 | 615 | static inline float _len(const V& v) 616 | { 617 | return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]); 618 | } 619 | 620 | static inline V& _norm(V& v) 621 | { 622 | const float len = 1.0f / _len(v); 623 | v[0] *= len; 624 | v[1] *= len; 625 | v[2] *= len; 626 | v[3] *= len; 627 | return v; 628 | } 629 | 630 | static inline void clamp(V& v, typename V::VecDataType low, typename V::VecDataType high) 631 | { 632 | CGE_CLAMP(v[0], low, high); 633 | CGE_CLAMP(v[1], low, high); 634 | CGE_CLAMP(v[2], low, high); 635 | CGE_CLAMP(v[3], low, high); 636 | } 637 | 638 | }; 639 | 640 | } 641 | 642 | namespace CGE 643 | { 644 | 645 | template 646 | class Vec 647 | { 648 | public: 649 | enum { VEC_DIM = DIM }; 650 | typedef Type VecDataType; 651 | 652 | Vec() { cgeStaticAssert(DIM > 0 && DIM <= 4);} 653 | Vec(const Vec& v) { VecAlgorithmHelp, DIM>::_assign(*this, v); } 654 | Vec(Type x) 655 | { 656 | cgeStaticAssert(DIM == 1); //DIM should be 1 657 | m_data[0] = x; 658 | } 659 | 660 | Vec(Type x, Type y) 661 | { 662 | cgeStaticAssert(DIM == 2); //DIM should be 2 663 | m_data[0] = x; 664 | m_data[1] = y; 665 | } 666 | 667 | Vec(Type x, Type y, Type z) 668 | { 669 | cgeStaticAssert(DIM == 3); //DIM should be 3 670 | m_data[0] = x; 671 | m_data[1] = y; 672 | m_data[2] = z; 673 | } 674 | Vec(Type x, Type y, Type z, Type w) 675 | { 676 | cgeStaticAssert(DIM == 4); //DIM should be 4 677 | m_data[0] = x; 678 | m_data[1] = y; 679 | m_data[2] = z; 680 | m_data[3] = w; 681 | } 682 | 683 | inline Type& operator[](int index) 684 | { 685 | return m_data[index]; 686 | } 687 | 688 | inline const Type& operator[](int index) const 689 | { 690 | return m_data[index]; 691 | } 692 | 693 | inline Vec operator+(const Vec& v)const 694 | { 695 | return VecAlgorithmHelp, DIM>::_plus(*this, v); 696 | } 697 | 698 | inline Vec operator+(Type t) const 699 | { 700 | return VecAlgorithmHelp, DIM>::_plus(*this, t); 701 | } 702 | 703 | inline friend Vec operator+(Type t, Vec& v) 704 | { 705 | return v + t; 706 | } 707 | 708 | inline Vec& operator+=(const Vec& v) 709 | { 710 | return VecAlgorithmHelp, DIM>::_inc(*this, v); 711 | } 712 | 713 | inline Vec& operator+=(Type t) 714 | { 715 | return VecAlgorithmHelp, DIM>::_inc(*this, t); 716 | } 717 | 718 | inline Vec operator-(const Vec& v)const 719 | { 720 | return VecAlgorithmHelp, DIM>::_minus(*this, v); 721 | } 722 | 723 | inline Vec operator-(Type t)const 724 | { 725 | return VecAlgorithmHelp, DIM>::_minus(*this, t); 726 | } 727 | 728 | inline Vec& operator-=(const Vec& v) 729 | { 730 | return VecAlgorithmHelp, DIM>::_sub(*this, v); 731 | } 732 | 733 | inline Vec& operator-=(Type t) 734 | { 735 | return VecAlgorithmHelp, DIM>::_sub(*this, t); 736 | } 737 | 738 | inline Vec operator*(const Vec& v)const 739 | { 740 | return VecAlgorithmHelp, DIM>::_times(*this, v); 741 | } 742 | 743 | inline Vec operator*(Type t)const 744 | { 745 | return VecAlgorithmHelp, DIM>::_times(*this, t); 746 | } 747 | 748 | inline Vec& operator*=(const Vec& v) 749 | { 750 | return VecAlgorithmHelp, DIM>::_mul(*this, v); 751 | } 752 | 753 | inline Vec& operator*=(Type t) 754 | { 755 | return VecAlgorithmHelp, DIM>::_mul(*this, t); 756 | } 757 | 758 | inline Vec operator/(const Vec& v)const 759 | { 760 | return VecAlgorithmHelp, DIM>::_divide(*this, v); 761 | } 762 | 763 | inline Vec operator/(Type t)const 764 | { 765 | return VecAlgorithmHelp, DIM>::_divide(*this, t); 766 | } 767 | 768 | inline Vec& operator/=(const Vec& v) 769 | { 770 | return VecAlgorithmHelp, DIM>::_div(*this, v); 771 | } 772 | 773 | inline Vec& operator/=(Type t) 774 | { 775 | return VecAlgorithmHelp, DIM>::_div(*this, t); 776 | } 777 | 778 | inline Vec& operator=(const Vec& v) 779 | { 780 | return VecAlgorithmHelp, DIM>::_assign(*this, v); 781 | } 782 | 783 | inline Vec& operator=(Type t) 784 | { 785 | return VecAlgorithmHelp, DIM>::_assign(*this, t); 786 | } 787 | 788 | inline Type dot(const Vec& v) const 789 | { 790 | return VecAlgorithmHelp, DIM>::_dot(*this, v); 791 | } 792 | 793 | inline Type dot() const 794 | { 795 | return VecAlgorithmHelp, DIM>::_dot(*this); 796 | } 797 | 798 | inline Type length() const 799 | { 800 | return VecAlgorithmHelp, DIM>::_len(*this); 801 | } 802 | 803 | inline Vec& normalize() 804 | { 805 | return VecAlgorithmHelp, DIM>::_norm(*this); 806 | } 807 | 808 | inline void clamp(Type low, Type high) 809 | { 810 | VecAlgorithmHelp, DIM>::_clamp(*this, low, high); 811 | } 812 | 813 | inline Type& x() { cgeStaticAssert(DIM >= 1); return m_data[0]; } 814 | inline Type& y() { cgeStaticAssert(DIM >= 2); return m_data[1]; } 815 | inline Type& z() { cgeStaticAssert(DIM >= 3); return m_data[2]; } 816 | inline Type& w() { cgeStaticAssert(DIM >= 4); return m_data[3]; } 817 | inline Type& r() { cgeStaticAssert(DIM >= 1); return m_data[0]; } 818 | inline Type& g() { cgeStaticAssert(DIM >= 2); return m_data[1]; } 819 | inline Type& b() { cgeStaticAssert(DIM >= 3); return m_data[2]; } 820 | inline Type& a() { cgeStaticAssert(DIM >= 4); return m_data[3]; } 821 | 822 | inline const Type& x() const { cgeStaticAssert(DIM >= 1); return m_data[0]; } 823 | inline const Type& y() const { cgeStaticAssert(DIM >= 2); return m_data[1]; } 824 | inline const Type& z() const { cgeStaticAssert(DIM >= 3); return m_data[2]; } 825 | inline const Type& w() const { cgeStaticAssert(DIM >= 4); return m_data[3]; } 826 | inline const Type& r() const { cgeStaticAssert(DIM >= 1); return m_data[0]; } 827 | inline const Type& g() const { cgeStaticAssert(DIM >= 2); return m_data[1]; } 828 | inline const Type& b() const { cgeStaticAssert(DIM >= 3); return m_data[2]; } 829 | inline const Type& a() const { cgeStaticAssert(DIM >= 4); return m_data[3]; } 830 | 831 | inline Type& get(int index) { return m_data[index]; } 832 | inline const Type& get(int index) const { return m_data[index]; } 833 | 834 | inline Vec subvec(int fst) const { return Vec(m_data[fst]); } 835 | inline Vec subvec(int fst, int scd) const { return Vec(m_data[fst], m_data[scd]); } 836 | inline Vec subvec(int fst, int scd, int trd) const { return Vec(m_data[fst], m_data[scd], m_data[trd]); } 837 | inline Vec subvec(int fst, int scd, int trd, int fth) const { return Vec(m_data[fst], m_data[scd], m_data[trd], m_data[fth]); } 838 | 839 | 840 | 841 | private: 842 | Type m_data[DIM]; 843 | }; 844 | 845 | typedef Vec Vec1b; 846 | typedef Vec Vec1ub; 847 | typedef Vec Vec1s; 848 | typedef Vec Vec1us; 849 | typedef Vec Vec1i; 850 | typedef Vec Vec1ui; 851 | typedef Vec1ui Vec1u; 852 | typedef Vec Vec1l; 853 | typedef Vec Vec1ul; 854 | typedef Vec Vec1ll; 855 | typedef Vec Vec1ull; 856 | typedef Vec Vec1f; 857 | typedef Vec Vec1d; 858 | typedef Vec Vec1ld; 859 | 860 | typedef Vec Vec2b; 861 | typedef Vec Vec2ub; 862 | typedef Vec Vec2s; 863 | typedef Vec Vec2us; 864 | typedef Vec Vec2i; 865 | typedef Vec Vec2ui; 866 | typedef Vec2ui Vec2u; 867 | typedef Vec Vec2l; 868 | typedef Vec Vec2ul; 869 | typedef Vec Vec2ll; 870 | typedef Vec Vec2ull; 871 | typedef Vec Vec2f; 872 | typedef Vec Vec2d; 873 | typedef Vec Vec2ld; 874 | 875 | typedef Vec Vec3b; 876 | typedef Vec Vec3ub; 877 | typedef Vec Vec3s; 878 | typedef Vec Vec3us; 879 | typedef Vec Vec3i; 880 | typedef Vec Vec3ui; 881 | typedef Vec3ui Vec3u; 882 | typedef Vec Vec3l; 883 | typedef Vec Vec3ul; 884 | typedef Vec Vec3ll; 885 | typedef Vec Vec3ull; 886 | typedef Vec Vec3f; 887 | typedef Vec Vec3d; 888 | typedef Vec Vec3ld; 889 | 890 | typedef Vec Vec4b; 891 | typedef Vec Vec4ub; 892 | typedef Vec Vec4s; 893 | typedef Vec Vec4us; 894 | typedef Vec Vec4i; 895 | typedef Vec Vec4ui; 896 | typedef Vec4ui Vec4u; 897 | typedef Vec Vec4l; 898 | typedef Vec Vec4ul; 899 | typedef Vec Vec4ll; 900 | typedef Vec Vec4ull; 901 | typedef Vec Vec4f; 902 | typedef Vec Vec4d; 903 | typedef Vec Vec4ld; 904 | 905 | inline Vec3f crossV3f(Vec3f left, Vec3f right) 906 | { 907 | return Vec3f(left[1] * right[2] - left[2] * right[1], 908 | left[2] * right[0] - left[0] * right[2], 909 | left[0] * right[1] - left[1] * right[0]); 910 | } 911 | 912 | inline Vec3f projectV3f(Vec3f v3ToProj, Vec3f projVec) 913 | { 914 | return projVec * (projVec.dot(v3ToProj) / projVec.dot()); 915 | } 916 | 917 | } 918 | 919 | #endif -------------------------------------------------------------------------------- /algorithm/cgeMat.h: -------------------------------------------------------------------------------- 1 | /* 2 | @Author: wysaid 3 | @Blog: blog.wysaid.org 4 | @Date: 2013-10-31 5 | @Description: Provide some cpu math algorithms like glsl shaders. 6 | @ Some algorithms are from http://www.opengl.org/ 7 | @Attention: I'm using radian, not degree! 8 | */ 9 | 10 | #ifndef _CGE_MAT_H_ 11 | #define _CGE_MAT_H_ 12 | 13 | #include 14 | #include 15 | #include "cgeStaticAssert.h" 16 | #include "cgeVec.h" 17 | 18 | #ifndef M_PI 19 | #define M_PI 3.141592653589793f 20 | #endif 21 | 22 | namespace CGE 23 | { 24 | inline void normalize(float& x, float& y, float& z) 25 | { 26 | const float scale = 1.0f / sqrtf(x*x + y*y + z*z); 27 | x *= scale; 28 | y *= scale; 29 | z *= scale; 30 | } 31 | 32 | inline void normalize(float& x, float& y, float& z, float& w) 33 | { 34 | const float scale = 1.0f / sqrtf(x*x + y*y + z*z + w*w); 35 | x *= scale; 36 | y *= scale; 37 | z *= scale; 38 | w *= scale; 39 | } 40 | 41 | struct Mat2 42 | { 43 | const static Mat2& makeIdentity() 44 | { 45 | const static Mat2 sIdentity = Mat2(1.0f, 0.0f, 46 | 0.0f, 1.0f); 47 | return sIdentity; 48 | } 49 | 50 | static inline Mat2& makeMatrix(Mat2& m, float m00, float m01, 51 | float m10, float m11) 52 | { 53 | m[0][0] = m00; 54 | m[0][1] = m01; 55 | m[1][0] = m10; 56 | m[1][1] = m11; 57 | return m; 58 | } 59 | 60 | static inline Mat2 makeRotation(float rad) 61 | { 62 | const float cosRad = cosf(rad); 63 | const float sinRad = sinf(rad); 64 | return Mat2(cosRad, sinRad, -sinRad, cosRad); 65 | } 66 | 67 | ////////////////////////////////////////////////////////////////////////// 68 | 69 | Mat2() {} 70 | Mat2(float m00, float m01, float m10, float m11) 71 | { 72 | makeMatrix(*this, m00, m01, m10, m11); 73 | } 74 | 75 | inline void rotate(float rad) 76 | { 77 | *this *= makeRotation(rad); 78 | } 79 | 80 | inline float* operator[](int index) 81 | { 82 | return data[index]; 83 | } 84 | 85 | inline const float* operator[](int index) const 86 | { 87 | return data[index]; 88 | } 89 | 90 | inline Vec2f operator*(const Vec2f& v) const 91 | { 92 | return Vec2f(data[0][0] * v[0] + data[1][0] * v[1], 93 | data[0][1] * v[0] + data[1][1] * v[1]); 94 | } 95 | 96 | inline Mat2 operator*(const Mat2& m) const 97 | { 98 | return Mat2(data[0][0] * m[0][0] + data[1][0] * m[0][1], 99 | data[0][1] * m[0][0] + data[1][1] * m[0][1], 100 | data[0][0] * m[1][0] + data[1][0] * m[1][1], 101 | data[0][1] * m[1][0] + data[1][1] * m[1][1] 102 | ); 103 | } 104 | 105 | inline Mat2& operator*=(const Mat2& m) 106 | { 107 | return *this = *this * m; 108 | } 109 | 110 | inline void loadIdentity() 111 | { 112 | *this = makeIdentity(); 113 | } 114 | 115 | float data[2][2]; 116 | }; 117 | 118 | struct Mat3 119 | { 120 | const static Mat3& makeIdentity() 121 | { 122 | const static Mat3 sIdentity = Mat3(1.0f, 0.0f, 0.0f, 123 | 0.0f, 1.0f, 0.0f, 124 | 0.0f, 0.0f, 1.0f); 125 | return sIdentity; 126 | } 127 | 128 | static inline Mat3& makeMatrix(Mat3& m, float m00, float m01, float m02, 129 | float m10, float m11, float m12, 130 | float m20, float m21, float m22) 131 | { 132 | m[0][0] = m00; 133 | m[0][1] = m01; 134 | m[0][2] = m02; 135 | m[1][0] = m10; 136 | m[1][1] = m11; 137 | m[1][2] = m12; 138 | m[2][0] = m20; 139 | m[2][1] = m21; 140 | m[2][2] = m22; 141 | return m; 142 | } 143 | 144 | static inline Mat3 makeRotation(float rad, float x, float y, float z) 145 | { 146 | normalize(x, y, z); 147 | const float cosRad = cosf(rad); 148 | const float cosp = 1.0f - cosRad; 149 | const float sinRad = sinf(rad); 150 | 151 | return Mat3(cosRad + cosp * x * x, 152 | cosp * x * y + z * sinRad, 153 | cosp * x * z - y * sinRad, 154 | cosp * x * y - z * sinRad, 155 | cosRad + cosp * y * y, 156 | cosp * y * z + x * sinRad, 157 | cosp * x * z + y * sinRad, 158 | cosp * y * z - x * sinRad, 159 | cosRad + cosp * z * z); 160 | } 161 | 162 | static inline Mat3 makeXRotation(float rad) 163 | { 164 | const float cosRad = cosf(rad); 165 | const float sinRad = sinf(rad); 166 | return Mat3(1.0f, 0.0f, 0.0f, 167 | 0.0f, cosRad, sinRad, 168 | 0.0f, -sinRad, cosRad); 169 | } 170 | 171 | static inline Mat3 makeYRotation(float rad) 172 | { 173 | const float cosRad = cosf(rad); 174 | const float sinRad = sinf(rad); 175 | return Mat3(cosRad, 0.0f, -sinRad, 176 | 0.0f, 1.0f, 0.0f, 177 | sinRad, 0.0f, cosRad); 178 | } 179 | 180 | static inline Mat3 makeZRotation(float rad) 181 | { 182 | const float cosRad = cosf(rad); 183 | const float sinRad = sinf(rad); 184 | return Mat3(cosRad, sinRad, 0.0f, 185 | -sinRad, cosRad, 0.0f, 186 | 0.0f, 0.0f, 1.0f); 187 | } 188 | 189 | ////////////////////////////////////////////////////////////////////////// 190 | 191 | Mat3() {} 192 | Mat3(float m00, float m01, float m02, 193 | float m10, float m11, float m12, 194 | float m20, float m21, float m22) 195 | { 196 | makeMatrix(*this, m00, m01, m02, 197 | m10, m11, m12, 198 | m20, m21, m22); 199 | } 200 | 201 | inline float* operator[](int index) 202 | { 203 | return data[index]; 204 | } 205 | 206 | inline const float* operator[](int index) const 207 | { 208 | return data[index]; 209 | } 210 | 211 | inline Vec3f operator*(const Vec3f& v) const 212 | { 213 | return Vec3f(data[0][0] * v[0] + data[1][0] * v[1] + data[2][0] * v[2], 214 | data[0][1] * v[0] + data[1][1] * v[1] + data[2][1] * v[2], 215 | data[0][2] * v[0] + data[1][2] * v[1] + data[2][2] * v[2]); 216 | } 217 | 218 | inline Mat3 operator*(const Mat3& m) const 219 | { 220 | return Mat3(data[0][0] * m[0][0] + data[1][0] * m[0][1] + data[2][0] * m[0][2], 221 | data[0][1] * m[0][0] + data[1][1] * m[0][1] + data[2][1] * m[0][2], 222 | data[0][2] * m[0][0] + data[1][2] * m[0][1] + data[2][2] * m[0][2], 223 | 224 | data[0][0] * m[1][0] + data[1][0] * m[1][1] + data[2][0] * m[1][2], 225 | data[0][1] * m[1][0] + data[1][1] * m[1][1] + data[2][1] * m[1][2], 226 | data[0][2] * m[1][0] + data[1][2] * m[1][1] + data[2][2] * m[1][2], 227 | 228 | data[0][0] * m[2][0] + data[1][0] * m[2][1] + data[2][0] * m[2][2], 229 | data[0][1] * m[2][0] + data[1][1] * m[2][1] + data[2][1] * m[2][2], 230 | data[0][2] * m[2][0] + data[1][2] * m[2][1] + data[2][2] * m[2][2]); 231 | } 232 | 233 | inline Mat3& operator*=(const Mat3& m) 234 | { 235 | return *this = *this * m; 236 | } 237 | 238 | inline void rotate(float rad, float x, float y, float z) 239 | { 240 | *this *= makeRotation(rad, x, y, z); 241 | } 242 | 243 | inline void rotateX(float rad) 244 | { 245 | *this *= makeXRotation(rad); //待优化 246 | } 247 | 248 | inline void rotateY(float rad) 249 | { 250 | *this *= makeYRotation(rad); //待优化 251 | } 252 | 253 | inline void rotateZ(float rad) 254 | { 255 | *this *= makeZRotation(rad); //待优化 256 | } 257 | 258 | inline void loadIdentity() 259 | { 260 | *this = makeIdentity(); 261 | } 262 | 263 | float data[3][3]; 264 | }; 265 | 266 | struct Mat4 267 | { 268 | const static inline Mat4& makeIdentity() 269 | { 270 | const static Mat4 sIdentity = Mat4(1.0f, 0.0f, 0.0f, 0.0f, 271 | 0.0f, 1.0f, 0.0f, 0.0f, 272 | 0.0f, 0.0f, 1.0f, 0.0f, 273 | 0.0f, 0.0f, 0.0f, 1.0f); 274 | return sIdentity; 275 | } 276 | 277 | static inline Mat4& makeMatrix(Mat4& m, float m00, float m01, float m02, float m03, 278 | float m10, float m11, float m12, float m13, 279 | float m20, float m21, float m22, float m23, 280 | float m30, float m31, float m32, float m33) 281 | { 282 | m[0][0] = m00; 283 | m[0][1] = m01; 284 | m[0][2] = m02; 285 | m[0][3] = m03; 286 | m[1][0] = m10; 287 | m[1][1] = m11; 288 | m[1][2] = m12; 289 | m[1][3] = m13; 290 | m[2][0] = m20; 291 | m[2][1] = m21; 292 | m[2][2] = m22; 293 | m[2][3] = m23; 294 | m[3][0] = m30; 295 | m[3][1] = m31; 296 | m[3][2] = m32; 297 | m[3][3] = m33; 298 | return m; 299 | } 300 | 301 | static inline Mat4& makeMatrixTranspose(Mat4& m, float m00, float m01, float m02, float m03, 302 | float m10, float m11, float m12, float m13, 303 | float m20, float m21, float m22, float m23, 304 | float m30, float m31, float m32, float m33) 305 | { 306 | m[0][0] = m00; 307 | m[0][1] = m10; 308 | m[0][2] = m20; 309 | m[0][3] = m30; 310 | m[1][0] = m01; 311 | m[1][1] = m11; 312 | m[1][2] = m21; 313 | m[1][3] = m31; 314 | m[2][0] = m02; 315 | m[2][1] = m12; 316 | m[2][2] = m22; 317 | m[2][3] = m32; 318 | m[3][0] = m03; 319 | m[3][1] = m13; 320 | m[3][2] = m23; 321 | m[3][3] = m33; 322 | return m; 323 | } 324 | 325 | static inline Mat4 makeMatrix(float m00, float m01, float m02, float m03, 326 | float m10, float m11, float m12, float m13, 327 | float m20, float m21, float m22, float m23, 328 | float m30, float m31, float m32, float m33) 329 | { 330 | return Mat4(m00, m01, m02, m03, 331 | m10, m11, m12, m13, 332 | m20, m21, m22, m23, 333 | m30, m31, m32, m33); 334 | } 335 | 336 | static inline Mat4 makeMatrixTranspose(float m00, float m01, float m02, float m03, 337 | float m10, float m11, float m12, float m13, 338 | float m20, float m21, float m22, float m23, 339 | float m30, float m31, float m32, float m33) 340 | { 341 | return Mat4(m00, m10, m20, m30, 342 | m01, m11, m21, m31, 343 | m02, m12, m22, m32, 344 | m03, m13, m23, m33); 345 | } 346 | 347 | static inline Mat4 makeTranslation(float x, float y, float z) 348 | { 349 | return Mat4(1.0f, 0.0f, 0.0f, 0.0f, 350 | 0.0f, 1.0f, 0.0f, 0.0f, 351 | 0.0f, 0.0f, 1.0f, 0.0f, 352 | x, y, z, 1.0f); 353 | } 354 | 355 | static inline Mat4 makeScale(float x, float y, float z) 356 | { 357 | return Mat4(x, 0.0f, 0.0f, 0.0f, 358 | 0.0f, y, 0.0f, 0.0f, 359 | 0.0f, 0.0f, z, 0.0f, 360 | 0.0f, 0.0f, 0.0f, 1.0f); 361 | } 362 | 363 | static inline Mat4 makeRotation(float rad, float x, float y, float z) 364 | { 365 | normalize(x, y, z); 366 | const float cosRad = cosf(rad); 367 | const float cosp = 1.0f - cosRad; 368 | const float sinRad = sinf(rad); 369 | 370 | return Mat4(cosRad + cosp * x * x, 371 | cosp * x * y + z * sinRad, 372 | cosp * x * z - y * sinRad, 373 | 0.0f, 374 | cosp * x * y - z * sinRad, 375 | cosRad + cosp * y * y, 376 | cosp * y * z + x * sinRad, 377 | 0.0f, 378 | cosp * x * z + y * sinRad, 379 | cosp * y * z - x * sinRad, 380 | cosRad + cosp * z * z, 381 | 0.0f, 382 | 0.0f, 383 | 0.0f, 384 | 0.0f, 385 | 1.0f); 386 | } 387 | 388 | static inline Mat4 makeXRotation(float rad) 389 | { 390 | const float cosRad = cosf(rad); 391 | const float sinRad = sinf(rad); 392 | return Mat4(1.0f, 0.0f, 0.0f, 0.0f, 393 | 0.0f, cosRad, sinRad, 0.0f, 394 | 0.0f, -sinRad, cosRad, 0.0f, 395 | 0.0f, 0.0f, 0.0f, 1.0f); 396 | } 397 | 398 | static inline Mat4 makeYRotation(float rad) 399 | { 400 | const float cosRad = cosf(rad); 401 | const float sinRad = sinf(rad); 402 | return Mat4(cosRad, 0.0f, -sinRad, 0.0f, 403 | 0.0f, 1.0f, 0.0f, 0.0f, 404 | sinRad, 0.0f, cosRad, 0.0f, 405 | 0.0f, 0.0f, 0.0f, 1.0f); 406 | } 407 | 408 | static inline Mat4 makeZRotation(float rad) 409 | { 410 | const float cosRad = cosf(rad); 411 | const float sinRad = sinf(rad); 412 | return Mat4(cosRad, sinRad, 0.0f, 0.0f, 413 | -sinRad, cosRad, 0.0f, 0.0f, 414 | 0.0f, 0.0f, 1.0f, 0.0f, 415 | 0.0f, 0.0f, 0.0f, 1.0f); 416 | } 417 | 418 | static inline Mat4 makePerspective(float fovyRad, float aspect, float nearZ, float farZ) 419 | { 420 | const float cotan = 1.0f / tanf(fovyRad / 2.0f); 421 | return Mat4(cotan / aspect, 0.0f, 0.0f, 0.0f, 422 | 0.0f, cotan, 0.0f, 0.0f, 423 | 0.0f, 0.0f, (farZ + nearZ) / (nearZ - farZ), -1.0f, 424 | 0.0f, 0.0f, (2.0f * farZ * nearZ) / (nearZ - farZ), 0.0f); 425 | } 426 | 427 | static inline Mat4 makeFrustum(float left, float right, float bottom, float top, float nearZ, float farZ) 428 | { 429 | const float ral = right + left; 430 | const float rsl = right - left; 431 | const float tsb = top - bottom; 432 | const float tab = top + bottom; 433 | const float fan = farZ + nearZ; 434 | const float fsn = farZ - nearZ; 435 | 436 | return Mat4(2.0f * nearZ / rsl, 0.0f, 0.0f, 0.0f, 437 | 0.0f, 2.0f * nearZ / tsb, 0.0f, 0.0f, 438 | ral / rsl, tab / tsb, -fan / fsn, -1.0f, 439 | 0.0f, 0.0f, (-2.0f * farZ * nearZ) / fsn, 0.0f); 440 | } 441 | 442 | static inline Mat4 makeOrtho(float left, float right, float bottom, float top, float nearZ, float farZ) 443 | { 444 | const float ral = right + left; 445 | const float rsl = right - left; 446 | const float tsb = top - bottom; 447 | const float tab = top + bottom; 448 | const float fan = farZ + nearZ; 449 | const float fsn = farZ - nearZ; 450 | 451 | return Mat4(2.0f / rsl, 0.0f, 0.0f, 0.0f, 452 | 0.0f, 2.0f / tsb, 0.0f, 0.0f, 453 | 0.0f, 0.0f, -2.0f / fsn, 0.0f, 454 | -ral / rsl, -tab / tsb, -fan / fsn, 1.0f); 455 | } 456 | 457 | static inline Mat4 makeLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) 458 | { 459 | Vec3f ev(eyeX, eyeY, eyeZ); 460 | Vec3f cv(centerX, centerY, centerZ); 461 | Vec3f uv(upX, upY, upZ); 462 | return makeLookAt(ev, cv, uv); 463 | } 464 | 465 | static inline Mat4 makeLookAt(const Vec3f& eye, const Vec3f& center, const Vec3f& up) 466 | { 467 | Vec3f forward((eye - center).normalize()); 468 | Vec3f side(crossV3f(up, forward).normalize()); 469 | Vec3f upVector(crossV3f(forward, side)); 470 | 471 | return Mat4(side[0], upVector[0], forward[0], 0.0f, 472 | side[1], upVector[1], forward[1], 0.0f, 473 | side[2], upVector[2], forward[2], 0.0f, 474 | -side.dot(eye), 475 | -upVector.dot(eye), 476 | -forward.dot(eye), 477 | 1.0f); 478 | } 479 | 480 | static inline Mat4 mat4Rotate(Mat4& m, float rad, float x, float y, float z) 481 | { 482 | return m * makeRotation(rad, x, y, z); 483 | } 484 | 485 | static inline Mat4 mat4RotateX(Mat4& m, float rad) 486 | { 487 | return m * makeXRotation(rad); 488 | } 489 | 490 | static inline Mat4 mat4RotateY(Mat4& m, float rad) 491 | { 492 | return m * makeYRotation(rad); 493 | } 494 | 495 | static inline Mat4 mat4RotateZ(Mat4& m, float rad) 496 | { 497 | return m * makeZRotation(rad); 498 | } 499 | 500 | static inline Vec3f mat4MulVec3WithTranslation(Mat4& m, Vec3f& v) 501 | { 502 | return Vec3f( 503 | m[0][0] * v[0] + m[0][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3], 504 | m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3], 505 | m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3]); 506 | } 507 | 508 | static inline Vec3f mat4MulAndProjVec3(Mat4& m, Vec3f& v3) 509 | { 510 | Vec4f v4 = m * Vec4f(v3[0], v3[1], v3[2], 1.0f); 511 | return Vec3f(v4[0], v4[1], v4[2]) / v4[3]; 512 | } 513 | 514 | static inline bool projectM4fPerspective(const Vec3f& obj, const Mat4& modelView, const Mat4& proj, const Vec4f& viewPort, Vec3f& winCoord) 515 | { 516 | //Transformation vectors 517 | float fTempo[8]; 518 | //modelView transform 519 | fTempo[0]=modelView[0][0]*obj[0]+modelView[1][0]*obj[1]+modelView[2][0]*obj[2]+modelView[3][0]; //w is always 1 520 | fTempo[1]=modelView[0][1]*obj[0]+modelView[1][1]*obj[1]+modelView[2][1]*obj[2]+modelView[3][1]; 521 | fTempo[2]=modelView[0][2]*obj[0]+modelView[1][2]*obj[1]+modelView[2][2]*obj[2]+modelView[3][2]; 522 | fTempo[3]=modelView[0][3]*obj[0]+modelView[1][3]*obj[1]+modelView[2][3]*obj[2]+modelView[3][3]; 523 | //proj transform, the final row of proj matrix is always [0.0, -1.0] 524 | //so we optimize for that. 525 | fTempo[4]=proj[0][0]*fTempo[0]+proj[1][0]*fTempo[1]+proj[2][0]*fTempo[2]+proj[3][0]*fTempo[3]; 526 | fTempo[5]=proj[0][1]*fTempo[0]+proj[1][1]*fTempo[1]+proj[2][1]*fTempo[2]+proj[3][1]*fTempo[3]; 527 | fTempo[6]=proj[0][2]*fTempo[0]+proj[1][2]*fTempo[1]+proj[2][2]*fTempo[2]+proj[3][2]*fTempo[3]; 528 | fTempo[7]=-fTempo[2]; 529 | //The result normalizes between -1 and 1 530 | if(fTempo[7]<=0.0f) //The w value 531 | return false; 532 | fTempo[7]=1.0f/fTempo[7]; 533 | //Perspective division 534 | fTempo[4]*=fTempo[7]; 535 | fTempo[5]*=fTempo[7]; 536 | fTempo[6]*=fTempo[7]; 537 | //Window coordinates 538 | //Map x, y to range 0-1 539 | winCoord[0]=(fTempo[4]*0.5f+0.5f)*viewPort[2]+viewPort[0]; 540 | winCoord[1]=(fTempo[5]*0.5f+0.5f)*viewPort[3]+viewPort[1]; 541 | //This is only correct when glDepthRange(0.0, 1.0) 542 | winCoord[2]=(1.0f+fTempo[6])*0.5f; //Between 0 and 1 543 | return true; 544 | } 545 | 546 | static inline bool projectM4fPerspective(const Vec3f& obj, const Mat4& modelView, const Mat4& proj, const Vec4f& viewPort, Vec2f& winCoord) 547 | { 548 | //Transformation vectors 549 | float fTempo[8]; 550 | //modelView transform 551 | fTempo[0]=modelView[0][0]*obj[0]+modelView[1][0]*obj[1]+modelView[2][0]*obj[2]+modelView[3][0]; //w is always 1 552 | fTempo[1]=modelView[0][1]*obj[0]+modelView[1][1]*obj[1]+modelView[2][1]*obj[2]+modelView[3][1]; 553 | fTempo[2]=modelView[0][2]*obj[0]+modelView[1][2]*obj[1]+modelView[2][2]*obj[2]+modelView[3][2]; 554 | fTempo[3]=modelView[0][3]*obj[0]+modelView[1][3]*obj[1]+modelView[2][3]*obj[2]+modelView[3][3]; 555 | //proj transform, the final row of proj matrix is always [0.0, -1.0] 556 | //so we optimize for that. 557 | fTempo[4]=proj[0][0]*fTempo[0]+proj[1][0]*fTempo[1]+proj[2][0]*fTempo[2]+proj[3][0]*fTempo[3]; 558 | fTempo[5]=proj[0][1]*fTempo[0]+proj[1][1]*fTempo[1]+proj[2][1]*fTempo[2]+proj[3][1]*fTempo[3]; 559 | fTempo[6]=proj[0][2]*fTempo[0]+proj[1][2]*fTempo[1]+proj[2][2]*fTempo[2]+proj[3][2]*fTempo[3]; 560 | fTempo[7]=-fTempo[2]; 561 | //The result normalizes between -1 and 1 562 | if(fTempo[7]<=0.0f) //The w value 563 | return false; 564 | fTempo[7]=1.0f/fTempo[7]; 565 | //Perspective division 566 | fTempo[4]*=fTempo[7]; 567 | fTempo[5]*=fTempo[7]; 568 | fTempo[6]*=fTempo[7]; 569 | //Window coordinates 570 | //Map x, y to range 0-1 571 | winCoord[0]=(fTempo[4]*0.5f+0.5f)*viewPort[2]+viewPort[0]; 572 | winCoord[1]=(fTempo[5]*0.5f+0.5f)*viewPort[3]+viewPort[1]; 573 | return true; 574 | } 575 | 576 | static inline bool projectM4f(const Vec3f& obj, const Mat4& modelView, const Mat4& proj, const Vec4f& viewport, Vec3f& winCoord) 577 | { 578 | Vec4f result = (modelView * Vec4f(obj[0], obj[1], obj[2], 1.0f)) * proj; 579 | 580 | if (result[3] <= 0.0f) 581 | return false; 582 | 583 | result[0] /= result[3]; 584 | result[1] /= result[3]; 585 | result[2] /= result[3]; 586 | 587 | winCoord[0] = viewport[0] + (1.0f + result[0]) * viewport[2] / 2.0f; 588 | winCoord[1] = viewport[1] + (1.0f + result[1]) * viewport[3] / 2.0f; 589 | 590 | winCoord[2] = (1.0f + result[2]) / 2.0f; 591 | return true; 592 | } 593 | 594 | static inline bool projectM4f(const Vec3f& obj, const Mat4& modelView, const Mat4& proj, const Vec4f& viewport, Vec2f& winCoord) 595 | { 596 | Vec4f result = (modelView * Vec4f(obj[0], obj[1], obj[2], 1.0f)) * proj; 597 | 598 | if (result[3] <= 0.0f) 599 | return false; 600 | 601 | result[0] /= result[3]; 602 | result[1] /= result[3]; 603 | result[2] /= result[3]; 604 | 605 | winCoord[0] = viewport[0] + (1.0f + result[0]) * viewport[2] / 2.0f; 606 | winCoord[1] = viewport[1] + (1.0f + result[1]) * viewport[3] / 2.0f; 607 | return true; 608 | } 609 | 610 | static inline bool projectM4f(const Vec2f& obj, const Mat4& modelView, const Mat4& proj, const Vec4f& viewport, Vec2f& winCoord) 611 | { 612 | Vec4f result = (modelView * Vec4f(obj[0], obj[1], 0.0f, 1.0f)) * proj; 613 | 614 | if (result[3] <= 0.0f) 615 | return false; 616 | 617 | result[0] /= result[3]; 618 | result[1] /= result[3]; 619 | result[2] /= result[3]; 620 | 621 | winCoord[0] = viewport[0] + (1.0f + result[0]) * viewport[2] / 2.0f; 622 | winCoord[1] = viewport[1] + (1.0f + result[1]) * viewport[3] / 2.0f; 623 | return true; 624 | } 625 | 626 | static inline bool projectM4f(const Vec3f& obj, const Mat4& modelViewProjection, const Vec4f& viewport, Vec3f& winCoord) 627 | { 628 | Vec4f result = modelViewProjection * Vec4f(obj[0], obj[1], obj[2], 1.0f); 629 | 630 | if (result[3] <= 0.0f) 631 | return false; 632 | 633 | result[0] /= result[3]; 634 | result[1] /= result[3]; 635 | result[2] /= result[3]; 636 | 637 | winCoord[0] = viewport[0] + (1.0f + result[0]) * viewport[2] / 2.0f; 638 | winCoord[1] = viewport[1] + (1.0f + result[1]) * viewport[3] / 2.0f; 639 | 640 | winCoord[2] = (1.0f + result[2]) / 2.0f; 641 | return true; 642 | } 643 | 644 | static inline bool projectM4f(const Vec3f& obj, const Mat4& modelViewProjection, const Vec4f& viewport, Vec2f& winCoord) 645 | { 646 | Vec4f result = modelViewProjection * Vec4f(obj[0], obj[1], obj[2], 1.0f); 647 | 648 | if (result[3] <= 0.0f) 649 | return false; 650 | 651 | result[0] /= result[3]; 652 | result[1] /= result[3]; 653 | result[2] /= result[3]; 654 | 655 | winCoord[0] = viewport[0] + (1.0f + result[0]) * viewport[2] / 2.0f; 656 | winCoord[1] = viewport[1] + (1.0f + result[1]) * viewport[3] / 2.0f; 657 | return true; 658 | } 659 | 660 | static inline bool projectM4f(const Vec3f& obj, const Mat4& modelView, const Mat4& proj, Vec2f& winCoord, float width = 1.0f, float height = 1.0f) 661 | { 662 | Vec4f result = (modelView * Vec4f(obj[0], obj[1], obj[2], 1.0f)) * proj; 663 | 664 | if (result[3] <= 0.0f) 665 | return false; 666 | 667 | result[0] /= result[3]; 668 | result[1] /= result[3]; 669 | 670 | winCoord[0] = (1.0f + result[0]) * width / 2.0f; 671 | winCoord[1] = (1.0f + result[1]) * height / 2.0f; 672 | return true; 673 | } 674 | 675 | //mvp = projectionMatrix * modelviewMatrix 676 | static inline bool projectM4f(const Vec3f& obj, const Mat4& mvp, Vec2f& winCoord, float width = 1.0f, float height = 1.0f) 677 | { 678 | Vec4f result = mvp * Vec4f(obj[0], obj[1], obj[2], 1.0f); 679 | 680 | if (result[3] <= 0.0f) 681 | return false; 682 | 683 | result[0] /= result[3]; 684 | result[1] /= result[3]; 685 | 686 | winCoord[0] = (1.0f + result[0]) * width / 2.0f; 687 | winCoord[1] = (1.0f + result[1]) * height / 2.0f; 688 | return true; 689 | } 690 | 691 | ////////////////////////////////////////////////////////////////////////// 692 | 693 | inline float* operator[](int index) 694 | { 695 | return data[index]; 696 | } 697 | 698 | inline const float* operator[](int index) const 699 | { 700 | return data[index]; 701 | } 702 | 703 | Mat4() {} 704 | Mat4(float m00, float m01, float m02, float m03, 705 | float m10, float m11, float m12, float m13, 706 | float m20, float m21, float m22, float m23, 707 | float m30, float m31, float m32, float m33) 708 | { 709 | makeMatrix(*this, m00, m01, m02, m03, 710 | m10, m11, m12, m13, 711 | m20, m21, m22, m23, 712 | m30, m31, m32, m33); 713 | } 714 | 715 | Mat4(float values[16]) 716 | { 717 | makeMatrix(*this, values[0], values[1], values[2], values[3], 718 | values[4], values[5], values[6], values[7], 719 | values[8], values[9], values[10], values[11], 720 | values[12], values[13], values[14], values[15]); 721 | } 722 | 723 | Mat4(Vec4f row0, Vec4f row1, Vec4f row2, Vec4f row3) 724 | { 725 | makeMatrix(*this, row0[0], row0[1], row0[2], row0[3], 726 | row1[0], row1[1], row1[2], row1[3], 727 | row2[0], row2[1], row2[2], row2[3], 728 | row3[0], row3[1], row3[2], row3[3]); 729 | } 730 | 731 | Mat4(Mat3& m, float v) 732 | { 733 | makeMatrix(*this, m[0][0], m[0][1], m[0][2], v, 734 | m[1][0], m[1][1], m[1][2], v, 735 | m[2][0], m[2][1], m[2][2], v, 736 | v, v, v, v); 737 | } 738 | 739 | inline const Mat4& transPose() 740 | { 741 | return makeMatrix(*this, data[0][0], data[1][0], data[2][0], data[3][0], 742 | data[0][1], data[1][1], data[2][1], data[3][1], 743 | data[0][2], data[1][2], data[2][2], data[3][2], 744 | data[0][3], data[1][3], data[2][3], data[3][3]); 745 | } 746 | 747 | inline void loadIdentity() 748 | { 749 | *this = makeIdentity(); 750 | } 751 | 752 | inline const Mat4& initWithQuaternion(float x, float y, float z, float w) 753 | { 754 | normalize(x, y, z, w); 755 | const float _2x = x + x; 756 | const float _2y = y + y; 757 | const float _2z = z + z; 758 | const float _2w = w + w; 759 | makeMatrix(*this, 1.0f - _2y * y - _2z * z, 760 | _2x * y + _2w * z, 761 | _2x * z - _2w * y, 762 | 0.0f, 763 | _2x * y - _2w * z, 764 | 1.0f - _2x * x - _2z * z, 765 | _2y * z + _2w * x, 766 | 0.0f, 767 | _2x * z + _2w * y, 768 | _2y * z - _2w * x, 769 | 1.0f - _2x * x - _2y * y, 770 | 0.0f, 771 | 0.0f, 772 | 0.0f, 773 | 0.0f, 774 | 1.0f); 775 | return *this; 776 | } 777 | 778 | inline Mat3 getMat3() 779 | { 780 | return Mat3(data[0][0], data[0][1], data[0][2], 781 | data[1][0], data[1][1], data[1][2], 782 | data[2][0], data[2][1], data[2][2]); 783 | } 784 | 785 | inline Mat2 getMat2() 786 | { 787 | return Mat2(data[0][0], data[0][1], 788 | data[1][0], data[1][1]); 789 | } 790 | 791 | inline Mat4 operator*(const Mat4& m) const 792 | { 793 | 794 | return Mat4(data[0][0] * m[0][0] + data[1][0] * m[0][1] + data[2][0] * m[0][2] + data[3][0] * m[0][3], 795 | data[0][1] * m[0][0] + data[1][1] * m[0][1] + data[2][1] * m[0][2] + data[3][1] * m[0][3], 796 | data[0][2] * m[0][0] + data[1][2] * m[0][1] + data[2][2] * m[0][2] + data[3][2] * m[0][3], 797 | data[0][3] * m[0][0] + data[1][3] * m[0][1] + data[2][3] * m[0][2] + data[3][3] * m[0][3], 798 | data[0][0] * m[1][0] + data[1][0] * m[1][1] + data[2][0] * m[1][2] + data[3][0] * m[1][3], 799 | data[0][1] * m[1][0] + data[1][1] * m[1][1] + data[2][1] * m[1][2] + data[3][1] * m[1][3], 800 | data[0][2] * m[1][0] + data[1][2] * m[1][1] + data[2][2] * m[1][2] + data[3][2] * m[1][3], 801 | data[0][3] * m[1][0] + data[1][3] * m[1][1] + data[2][3] * m[1][2] + data[3][3] * m[1][3], 802 | data[0][0] * m[2][0] + data[1][0] * m[2][1] + data[2][0] * m[2][2] + data[3][0] * m[2][3], 803 | data[0][1] * m[2][0] + data[1][1] * m[2][1] + data[2][1] * m[2][2] + data[3][1] * m[2][3], 804 | data[0][2] * m[2][0] + data[1][2] * m[2][1] + data[2][2] * m[2][2] + data[3][2] * m[2][3], 805 | data[0][3] * m[2][0] + data[1][3] * m[2][1] + data[2][3] * m[2][2] + data[3][3] * m[2][3], 806 | data[0][0] * m[3][0] + data[1][0] * m[3][1] + data[2][0] * m[3][2] + data[3][0] * m[3][3], 807 | data[0][1] * m[3][0] + data[1][1] * m[3][1] + data[2][1] * m[3][2] + data[3][1] * m[3][3], 808 | data[0][2] * m[3][0] + data[1][2] * m[3][1] + data[2][2] * m[3][2] + data[3][2] * m[3][3], 809 | data[0][3] * m[3][0] + data[1][3] * m[3][1] + data[2][3] * m[3][2] + data[3][3] * m[3][3]); 810 | } 811 | 812 | //特殊用法, 将mat3 直接转换为mat4 并与之相乘。 813 | inline Mat4 operator*(const Mat3& m) const 814 | { 815 | return Mat4(data[0][0] * m[0][0] + data[1][0] * m[0][1] + data[2][0] * m[0][2], 816 | data[0][1] * m[0][0] + data[1][1] * m[0][1] + data[2][1] * m[0][2], 817 | data[0][2] * m[0][0] + data[1][2] * m[0][1] + data[2][2] * m[0][2], 818 | data[0][3] * m[0][0] + data[1][3] * m[0][1] + data[2][3] * m[0][2], 819 | data[0][0] * m[1][0] + data[1][0] * m[1][1] + data[2][0] * m[1][2], 820 | data[0][1] * m[1][0] + data[1][1] * m[1][1] + data[2][1] * m[1][2], 821 | data[0][2] * m[1][0] + data[1][2] * m[1][1] + data[2][2] * m[1][2], 822 | data[0][3] * m[1][0] + data[1][3] * m[1][1] + data[2][3] * m[1][2], 823 | data[0][0] * m[2][0] + data[1][0] * m[2][1] + data[2][0] * m[2][2], 824 | data[0][1] * m[2][0] + data[1][1] * m[2][1] + data[2][1] * m[2][2], 825 | data[0][2] * m[2][0] + data[1][2] * m[2][1] + data[2][2] * m[2][2], 826 | data[0][3] * m[2][0] + data[1][3] * m[2][1] + data[2][3] * m[2][2], 827 | data[3][0], 828 | data[3][1], 829 | data[3][2], 830 | data[3][3]); 831 | } 832 | 833 | inline Mat4& operator*=(const Mat4& m) 834 | { 835 | *this = *this * m; 836 | return *this; 837 | } 838 | 839 | inline Vec4f operator*(const Vec4f& v) const 840 | { 841 | return Vec4f( 842 | data[0][0] * v[0] + data[1][0] * v[1] + data[2][0] * v[2] + data[3][0] * v[3], 843 | data[0][1] * v[0] + data[1][1] * v[1] + data[2][1] * v[2] + data[3][1] * v[3], 844 | data[0][2] * v[0] + data[1][2] * v[1] + data[2][2] * v[2] + data[3][2] * v[3], 845 | data[0][3] * v[0] + data[1][3] * v[1] + data[2][3] * v[2] + data[3][3] * v[3]); 846 | } 847 | 848 | inline Vec3f operator*(const Vec3f& v) const 849 | { 850 | return Vec3f(data[0][0] * v[0] + data[1][0] * v[1] + data[2][0] * v[2], 851 | data[0][1] * v[0] + data[1][1] * v[1] + data[2][1] * v[2], 852 | data[0][2] * v[0] + data[1][2] * v[1] + data[2][2] * v[2]); 853 | } 854 | 855 | friend inline Vec4f operator*(const Vec4f& v, const Mat4& m) 856 | { 857 | return m * v; 858 | } 859 | 860 | friend inline Vec3f operator*(const Vec3f& v, const Mat4& m) 861 | { 862 | return m * v; 863 | } 864 | 865 | inline Mat4 operator+(const Mat4& m) const 866 | { 867 | return Mat4( data[0][0] + m[0][0], 868 | data[0][1] + m[0][1], 869 | data[0][2] + m[0][2], 870 | data[0][3] + m[0][3], 871 | 872 | data[1][0] + m[1][0], 873 | data[1][1] + m[1][1], 874 | data[1][2] + m[1][2], 875 | data[1][3] + m[1][3], 876 | 877 | data[2][0] + m[2][0], 878 | data[2][1] + m[2][1], 879 | data[2][2] + m[2][2], 880 | data[2][3] + m[2][3], 881 | 882 | data[3][0] + m[3][0], 883 | data[3][1] + m[3][1], 884 | data[3][2] + m[3][2], 885 | data[3][3] + m[3][3]); 886 | } 887 | 888 | inline Mat4& operator+=(const Mat4& m) 889 | { 890 | *this = *this + m; 891 | return *this; 892 | } 893 | 894 | inline Mat4 operator-(const Mat4& m) const 895 | { 896 | return Mat4(data[0][0] - m[0][0], 897 | data[0][1] - m[0][1], 898 | data[0][2] - m[0][2], 899 | data[0][3] - m[0][3], 900 | 901 | data[1][0] - m[1][0], 902 | data[1][1] - m[1][1], 903 | data[1][2] - m[1][2], 904 | data[1][3] - m[1][3], 905 | 906 | data[2][0] - m[2][0], 907 | data[2][1] - m[2][1], 908 | data[2][2] - m[2][2], 909 | data[2][3] - m[2][3], 910 | 911 | data[3][0] - m[3][0], 912 | data[3][1] - m[3][1], 913 | data[3][2] - m[3][2], 914 | data[3][3] - m[3][3]); 915 | } 916 | 917 | inline Mat4& operator-=(const Mat4& m) 918 | { 919 | *this = *this - m; 920 | return *this; 921 | } 922 | 923 | inline void translateX(float x) 924 | { 925 | data[3][0] += data[0][0] * x; 926 | data[3][1] += data[0][1] * x; 927 | data[3][2] += data[0][2] * x; 928 | } 929 | 930 | inline void translateY(float y) 931 | { 932 | data[3][0] += data[1][0] * y; 933 | data[3][1] += data[1][1] * y; 934 | data[3][2] += data[1][2] * y; 935 | } 936 | 937 | inline void translateZ(float z) 938 | { 939 | data[3][0] += data[2][0] * z; 940 | data[3][1] += data[2][1] * z; 941 | data[3][2] += data[2][2] * z; 942 | } 943 | 944 | inline void translate(float x, float y, float z) 945 | { 946 | data[3][0] += data[0][0] * x + data[1][0] * y + data[2][0] * z; 947 | data[3][1] += data[0][1] * x + data[1][1] * y + data[2][1] * z; 948 | data[3][2] += data[0][2] * x + data[1][2] * y + data[2][2] * z; 949 | } 950 | 951 | inline void scaleX(float x) 952 | { 953 | data[0][0] *= x; 954 | data[0][1] *= x; 955 | data[0][2] *= x; 956 | data[0][3] *= x; 957 | } 958 | 959 | inline void scaleY(float y) 960 | { 961 | data[1][0] *= y; 962 | data[1][1] *= y; 963 | data[1][2] *= y; 964 | data[1][3] *= y; 965 | } 966 | 967 | inline void scaleZ(float z) 968 | { 969 | data[2][0] *= z; 970 | data[2][1] *= z; 971 | data[2][2] *= z; 972 | data[2][3] *= z; 973 | } 974 | 975 | inline void scale(float x, float y, float z) 976 | { 977 | scaleX(x); 978 | scaleY(y); 979 | scaleZ(z); 980 | } 981 | 982 | inline void rotate(float rad, float x, float y, float z) 983 | { 984 | *this *= makeRotation(rad, x, y, z); 985 | } 986 | 987 | inline void rotateX(float rad) 988 | { 989 | *this *= makeXRotation(rad); 990 | } 991 | 992 | inline void rotateY(float rad) 993 | { 994 | *this *= makeYRotation(rad); 995 | } 996 | 997 | inline void rotateZ(float rad) 998 | { 999 | *this *= makeZRotation(rad); 1000 | } 1001 | 1002 | inline Mat3 toMat3() 1003 | { 1004 | return Mat3(data[0][0], data[0][1], data[0][2], 1005 | data[1][0], data[1][1], data[1][2], 1006 | data[2][0], data[2][1], data[2][2]); 1007 | } 1008 | 1009 | float data[4][4]; 1010 | }; 1011 | 1012 | } 1013 | 1014 | #endif -------------------------------------------------------------------------------- /ege/include/ege.h: -------------------------------------------------------------------------------- 1 | /********************************************************* 2 | * EGE (Easy Graphics Engine) 24.04 3 | * FileName: ege.h 4 | * Website: https://xege.org 5 | * Community: https://club.xege.org 6 | * GitHub: https://github.com/wysaid/xege 7 | * GitHub: https://github.com/Easy-Graphics-Engine 8 | * Gitee: https://gitee.com/xege/xege 9 | * Blog: https://wysaid.org 10 | * E-Mail: this@wysaid.org 11 | * E-Mail: misakamm@gmail.com 12 | * 13 | *********************************************************/ 14 | 15 | #ifndef EGE_H 16 | #define EGE_H 17 | 18 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 19 | #pragma once 20 | #endif 21 | 22 | // Easy Graphics Engine Version 23 | // Calendar Versioning, format: YY.0M.PatchNumber (If the PatchNumber equals 0, the YY.0M format is used.) 24 | #define EGE_VERSION "24.04" 25 | #define EGE_VERSION_MAJOR 24 26 | #define EGE_VERSION_MINOR 4 27 | #define EGE_VERSION_PATCH 0 28 | #define EGE_MAKE_VERSION_NUMBER(major, minor, patch) ((major) * 10000L + (minor) * 100L + (patch)) 29 | #define EGE_VERSION_NUMBER EGE_MAKE_VERSION_NUMBER(EGE_VERSION_MAJOR, EGE_VERSION_MINOR, EGE_VERSION_PATCH) 30 | 31 | #ifndef __cplusplus 32 | #error You must use a C++ compiler and ensure that your source files is named with the '.cpp' suffix. 33 | #endif 34 | 35 | #if defined(_INC_CONIO) || defined(_CONIO_H_) 36 | #error You cannot include "conio.h" before "graphics.h". 37 | #endif 38 | 39 | #if defined(_MSC_VER) 40 | # pragma warning(disable: 4355) 41 | # ifndef _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH 42 | # define _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH 43 | # endif 44 | # ifndef _ALLOW_RUNTIME_LIBRARY_MISMATCH 45 | # define _ALLOW_RUNTIME_LIBRARY_MISMATCH 46 | # endif 47 | #endif 48 | 49 | #if !defined(EGE_GRAPH_LIB_BUILD) && !defined(EGE_GRAPH_NO_LIB) 50 | # ifdef _MSC_VER 51 | # pragma comment(lib,"gdiplus.lib") 52 | # ifdef _WIN64 // 64 bit libs 53 | # pragma comment(lib,"graphics.lib") 54 | # else // 32 bit libs 55 | # pragma comment(lib,"graphics.lib") 56 | # endif 57 | # endif 58 | #endif 59 | 60 | 61 | #if !defined(EGE_GRAPH_LIB_BUILD) && !defined(EGE_GRAPH_NO_LIB) 62 | #ifndef _CRT_SECURE_NO_WARNINGS 63 | #define _CRT_SECURE_NO_WARNINGS 64 | #endif 65 | 66 | #ifndef _CRT_SECURE_NO_DEPRECATE 67 | #define _CRT_SECURE_NO_DEPRECATE 68 | #endif 69 | 70 | #ifndef _CRT_NON_CONFORMING_SWPRINTFS 71 | #define _CRT_NON_CONFORMING_SWPRINTFS 72 | #endif 73 | #endif 74 | 75 | 76 | #if defined(EGE_FOR_AUTO_CODE_COMPLETETION_ONLY) 77 | #include 78 | #include 79 | #include 80 | #else 81 | #include 82 | #endif 83 | 84 | #if defined(_MSC_VER) && (_MSC_VER <= 1300) 85 | #define EGE_COMPILERINFO_VC6 86 | #endif 87 | 88 | #if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(SetWindowLongPtr) 89 | # define SetWindowLongPtrW SetWindowLongW 90 | # define GetWindowLongPtrW GetWindowLongW 91 | # define GWLP_USERDATA GWL_USERDATA 92 | # define GWLP_WNDPROC GWL_WNDPROC 93 | #endif 94 | 95 | #ifndef WM_MOUSEWHEEL 96 | #define WM_MOUSEWHEEL 0x020A 97 | #endif 98 | 99 | #ifndef EGE_CDECL 100 | # if __STDC__ 101 | # define EGE_CDECL __cdecl 102 | # else 103 | # define EGE_CDECL __cdecl 104 | # endif 105 | #endif 106 | 107 | #ifdef _MSC_VER 108 | # if defined(_WIN64) 109 | # define EGEAPI 110 | # else 111 | # define EGEAPI EGE_CDECL 112 | # endif 113 | #else 114 | # if defined(__WORDSIZE) 115 | # if __WORDSIZE > 32 116 | # define EGEAPI 117 | # else 118 | # define EGEAPI EGE_CDECL 119 | # endif 120 | # else 121 | # define EGEAPI 122 | # endif 123 | #endif 124 | 125 | #ifndef EGE_DEPRECATE 126 | # ifdef _MSC_VER 127 | # ifdef _CRT_DEPRECATE_TEXT 128 | # define EGE_DEPRECATE(function, msg) _CRT_DEPRECATE_TEXT("This function is deprecated. " msg " For more information, visit https://xege.org/.") 129 | # else 130 | # define EGE_DEPRECATE(function, msg) 131 | # endif 132 | # elif ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))) 133 | # define EGE_DEPRECATE(function, msg) __attribute__((deprecated(msg " For more information, visit https://xege.org/."))) 134 | # else 135 | # define EGE_DEPRECATE(function, msg) __attribute__((deprecated)) 136 | # endif 137 | #endif 138 | 139 | #define EGE_GDIPLUS 140 | 141 | #define EGERGBA(r, g, b, a) ((::ege::color_t)(((r) << 16) | ((g) << 8) | (b) | ((a) << 24))) 142 | #define EGERGB(r, g, b) EGERGBA(r, g, b, 0xFF) 143 | #define EGEARGB(a, r, g, b) EGERGBA(r, g, b, a) 144 | #define EGEACOLOR(a, color) ((::ege::color_t)(((color) & 0xFFFFFF) | ((a) << 24))) 145 | #define EGECOLORA(color, a) EGEACOLOR(a, color) 146 | #define EGEGET_R(c) (((c) >> 16) & 0xFF) 147 | #define EGEGET_G(c) (((c) >> 8) & 0xFF) 148 | #define EGEGET_B(c) (((c)) & 0xFF) 149 | #define EGEGET_A(c) (((c) >> 24) & 0xFF) 150 | #define EGEGRAY(gray) EGERGB(gray, gray, gray) 151 | #define EGEGRAYA(gray, a) EGERGBA(gray, gray, gray, a) 152 | #define EGEAGRAY(a, gray) EGEGRAYA(gray, a) 153 | 154 | /* you can also use 932 as shift-jis, 950 as big5 ... */ 155 | /* see https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers */ 156 | #define EGE_CODEPAGE_GB2312 936 157 | #define EGE_CODEPAGE_UTF8 65001 158 | #define EGE_CODEPAGE_ANSI 0 159 | 160 | namespace ege 161 | { 162 | 163 | const double PI = 3.1415926535897932384626; 164 | 165 | /* define graphics drivers */ 166 | enum graphics_drivers 167 | { 168 | DETECT = 0, /* requests autodetection */ 169 | CGA, MCGA, EGA, EGA64, EGAMONO, IBM8514,/* 1 - 6 */ 170 | HERCMONO, ATT400, VGA, PC3270, /* 7 - 10 */ 171 | TRUECOLOR, TRUECOLORSIZE, 172 | CURRENT_DRIVER = -1 173 | }; 174 | 175 | /* graphics modes for each driver */ 176 | enum graphics_modes 177 | { 178 | CGAC0 = 0, /* 320x200 palette 0; 1 page */ 179 | CGAC1 = 1, /* 320x200 palette 1; 1 page */ 180 | CGAC2 = 2, /* 320x200 palette 2: 1 page */ 181 | CGAC3 = 3, /* 320x200 palette 3; 1 page */ 182 | CGAHI = 4, /* 640x200 1 page */ 183 | MCGAC0 = 0, /* 320x200 palette 0; 1 page */ 184 | MCGAC1 = 1, /* 320x200 palette 1; 1 page */ 185 | MCGAC2 = 2, /* 320x200 palette 2; 1 page */ 186 | MCGAC3 = 3, /* 320x200 palette 3; 1 page */ 187 | MCGAMED = 4, /* 640x200 1 page */ 188 | MCGAHI = 5, /* 640x480 1 page */ 189 | EGALO = 0, /* 640x200 16 color 4 pages */ 190 | EGAHI = 1, /* 640x350 16 color 2 pages */ 191 | EGA64LO = 0, /* 640x200 16 color 1 page */ 192 | EGA64HI = 1, /* 640x350 4 color 1 page */ 193 | EGAMONOHI = 0, /* 640x350 64K on card, 1 page - 256K on card, 4 pages */ 194 | HERCMONOHI = 0, /* 720x348 2 pages */ 195 | ATT400C0 = 0, /* 320x200 palette 0; 1 page */ 196 | ATT400C1 = 1, /* 320x200 palette 1; 1 page */ 197 | ATT400C2 = 2, /* 320x200 palette 2; 1 page */ 198 | ATT400C3 = 3, /* 320x200 palette 3; 1 page */ 199 | ATT400MED = 4, /* 640x200 1 page */ 200 | ATT400HI = 5, /* 640x400 1 page */ 201 | VGALO = 0, /* 640x200 16 color 4 pages */ 202 | VGAMED = 1, /* 640x350 16 color 2 pages */ 203 | VGAHI = 2, /* 640x480 16 color 1 page */ 204 | PC3270HI = 0, /* 720x350 1 page */ 205 | IBM8514LO = 0, /* 640x480 256 colors */ 206 | IBM8514HI = 1 /*1024x768 256 colors */ 207 | }; 208 | 209 | enum initmode_flag 210 | { 211 | INIT_DEFAULT = 0x0, 212 | INIT_NOBORDER = 0x1, 213 | INIT_CHILD = 0x2, 214 | INIT_TOPMOST = 0x4, 215 | INIT_RENDERMANUAL = 0x8, 216 | INIT_NOFORCEEXIT = 0x10, 217 | INIT_UNICODE = 0x20, // equal to setunicodecharmessage(true) 218 | INIT_HIDE = 0x40, 219 | INIT_WITHLOGO = 0x100, 220 | INIT_ANIMATION = INIT_DEFAULT | INIT_RENDERMANUAL | INIT_NOFORCEEXIT, 221 | }; 222 | 223 | enum rendermode_e 224 | { 225 | RENDER_AUTO, 226 | RENDER_MANUAL, 227 | }; 228 | 229 | /* graphresult error return codes */ 230 | enum graphics_errors 231 | { 232 | grOk = 0, 233 | grNoInitGraph = -1, 234 | grNotDetected = -2, 235 | grFileNotFound = -3, 236 | grInvalidDriver = -4, 237 | grNoLoadMem = -5, 238 | grNoScanMem = -6, 239 | grNoFloodMem = -7, 240 | grFontNotFound = -8, 241 | grNoFontMem = -9, 242 | grInvalidMode = -10, 243 | grError = -11, /* generic error */ 244 | grIOerror = -12, 245 | grInvalidFont = -13, 246 | grInvalidFontNum = -14, 247 | grInvalidVersion = -18, 248 | 249 | grException = 0x10, /* ege error */ 250 | grParamError = 0x11, 251 | grInvalidRegion = 0x12, 252 | grOutOfMemory = 0x13, 253 | grNullPointer = 0x14, 254 | grAllocError = 0x15, 255 | grInvalidMemory = 0xCDCDCDCD, 256 | }; 257 | 258 | enum message_event 259 | { 260 | MSG_EVENT_UP = 0x00, 261 | MSG_EVENT_DOWN = 0x01, 262 | MSG_EVENT_CLICK = 0x01, 263 | MSG_EVENT_DBCLICK = 0x02, 264 | MSG_EVENT_MOVE = 0x04, 265 | MSG_EVENT_WHEEL = 0x10, 266 | }; 267 | 268 | enum message_mouse 269 | { 270 | MSG_MOUSE_LEFT = 0x01, 271 | MSG_MOUSE_RIGHT = 0x02, 272 | MSG_MOUSE_MID = 0x04, 273 | }; 274 | 275 | 276 | #ifndef EGE_COLOR_T_TYPEDEF 277 | #define EGE_COLOR_T_TYPEDEF 278 | typedef unsigned int color_t; 279 | #endif 280 | 281 | enum alpha_type 282 | { 283 | ALPHATYPE_STRAIGHT = 0, 284 | ALPHATYPE_PREMULTIPLIED = 1, 285 | }; 286 | 287 | struct ege_point 288 | { 289 | float x; 290 | float y; 291 | }; 292 | 293 | struct ege_rect 294 | { 295 | float x; 296 | float y; 297 | float w; 298 | float h; 299 | }; 300 | 301 | struct ege_colpoint 302 | { 303 | float x; 304 | float y; 305 | color_t color; 306 | }; 307 | 308 | enum COLORS 309 | { 310 | ALICEBLUE = EGERGB(0xF0, 0xF8, 0xFF), 311 | ANTIQUEWHITE = EGERGB(0xFA, 0xEB, 0xD7), 312 | AQUA = EGERGB(0x00, 0xFF, 0xFF), 313 | AQUAMARINE = EGERGB(0x7F, 0xFF, 0xD4), 314 | AZURE = EGERGB(0xF0, 0xFF, 0xFF), 315 | BEIGE = EGERGB(0xF5, 0xF5, 0xDC), 316 | BISQUE = EGERGB(0xFF, 0xE4, 0xC4), 317 | BLACK = EGERGB(0x00, 0x00, 0x00), 318 | BLANCHEDALMOND = EGERGB(0xFF, 0xEB, 0xCD), 319 | BLUE = EGERGB(0x00, 0x00, 0xFF), 320 | BLUEVIOLET = EGERGB(0x8A, 0x2B, 0xE2), 321 | BROWN = EGERGB(0xA5, 0x2A, 0x2A), 322 | BURLYWOOD = EGERGB(0xDE, 0xB8, 0x87), 323 | CADETBLUE = EGERGB(0x5F, 0x9E, 0xA0), 324 | CHARTREUSE = EGERGB(0x7F, 0xFF, 0x00), 325 | CHOCOLATE = EGERGB(0xD2, 0x69, 0x1E), 326 | CORAL = EGERGB(0xFF, 0x7F, 0x50), 327 | CORNFLOWERBLUE = EGERGB(0x64, 0x95, 0xED), 328 | CORNSILK = EGERGB(0xFF, 0xF8, 0xDC), 329 | CRIMSON = EGERGB(0xDC, 0x14, 0x3C), 330 | CYAN = EGERGB(0x00, 0xFF, 0xFF), 331 | DARKBLUE = EGERGB(0x00, 0x00, 0x8B), 332 | DARKCYAN = EGERGB(0x00, 0x8B, 0x8B), 333 | DARKGOLDENROD = EGERGB(0xB8, 0x86, 0x0B), 334 | DARKGRAY = EGERGB(0xA9, 0xA9, 0xA9), 335 | DARKGREEN = EGERGB(0x00, 0x64, 0x00), 336 | DARKKHAKI = EGERGB(0xBD, 0xB7, 0x6B), 337 | DARKMAGENTA = EGERGB(0x8B, 0x00, 0x8B), 338 | DARKOLIVEGREEN = EGERGB(0x55, 0x6B, 0x2F), 339 | DARKORANGE = EGERGB(0xFF, 0x8C, 0x00), 340 | DARKORCHID = EGERGB(0x99, 0x32, 0xCC), 341 | DARKRED = EGERGB(0x8B, 0x00, 0x00), 342 | DARKSALMON = EGERGB(0xE9, 0x96, 0x7A), 343 | DARKSEAGREEN = EGERGB(0x8F, 0xBC, 0x8F), 344 | DARKSLATEBLUE = EGERGB(0x48, 0x3D, 0x8B), 345 | DARKSLATEGRAY = EGERGB(0x2F, 0x4F, 0x4F), 346 | DARKTURQUOISE = EGERGB(0x00, 0xCE, 0xD1), 347 | DARKVIOLET = EGERGB(0x94, 0x00, 0xD3), 348 | DEEPPINK = EGERGB(0xFF, 0x14, 0x93), 349 | DEEPSKYBLUE = EGERGB(0x00, 0xBF, 0xFF), 350 | DIMGRAY = EGERGB(0x69, 0x69, 0x69), 351 | DODGERBLUE = EGERGB(0x1E, 0x90, 0xFF), 352 | FIREBRICK = EGERGB(0xB2, 0x22, 0x22), 353 | FLORALWHITE = EGERGB(0xFF, 0xFA, 0xF0), 354 | FORESTGREEN = EGERGB(0x22, 0x8B, 0x22), 355 | FUCHSIA = EGERGB(0xFF, 0x00, 0xFF), 356 | GAINSBORO = EGERGB(0xDC, 0xDC, 0xDC), 357 | GHOSTWHITE = EGERGB(0xF8, 0xF8, 0xFF), 358 | GOLD = EGERGB(0xFF, 0xD7, 0x00), 359 | GOLDENROD = EGERGB(0xDA, 0xA5, 0x20), 360 | GRAY = EGERGB(0x80, 0x80, 0x80), 361 | GREEN = EGERGB(0x00, 0x80, 0x00), 362 | GREENYELLOW = EGERGB(0xAD, 0xFF, 0x2F), 363 | HONEYDEW = EGERGB(0xF0, 0xFF, 0xF0), 364 | HOTPINK = EGERGB(0xFF, 0x69, 0xB4), 365 | INDIANRED = EGERGB(0xCD, 0x5C, 0x5C), 366 | INDIGO = EGERGB(0x4B, 0x00, 0x82), 367 | IVORY = EGERGB(0xFF, 0xFF, 0xF0), 368 | KHAKI = EGERGB(0xF0, 0xE6, 0x8C), 369 | LAVENDER = EGERGB(0xE6, 0xE6, 0xFA), 370 | LAVENDERBLUSH = EGERGB(0xFF, 0xF0, 0xF5), 371 | LAWNGREEN = EGERGB(0x7C, 0xFC, 0x00), 372 | LEMONCHIFFON = EGERGB(0xFF, 0xFA, 0xCD), 373 | LIGHTBLUE = EGERGB(0xAD, 0xD8, 0xE6), 374 | LIGHTCORAL = EGERGB(0xF0, 0x80, 0x80), 375 | LIGHTCYAN = EGERGB(0xE0, 0xFF, 0xFF), 376 | LIGHTGOLDENRODYELLOW = EGERGB(0xFA, 0xFA, 0xD2), 377 | LIGHTGRAY = EGERGB(0xD3, 0xD3, 0xD3), 378 | LIGHTGREEN = EGERGB(0x90, 0xEE, 0x90), 379 | LIGHTPINK = EGERGB(0xFF, 0xB6, 0xC1), 380 | LIGHTSALMON = EGERGB(0xFF, 0xA0, 0x7A), 381 | LIGHTSEAGREEN = EGERGB(0x20, 0xB2, 0xAA), 382 | LIGHTSKYBLUE = EGERGB(0x87, 0xCE, 0xFA), 383 | LIGHTSLATEGRAY = EGERGB(0x77, 0x88, 0x99), 384 | LIGHTSTEELBLUE = EGERGB(0xB0, 0xC4, 0xDE), 385 | LIGHTYELLOW = EGERGB(0xFF, 0xFF, 0xE0), 386 | LIGHTRED = EGERGB(0xFC, 0x54, 0x54), 387 | LIGHTMAGENTA = EGERGB(0xFC, 0x54, 0xFC), 388 | LIME = EGERGB(0x00, 0xFF, 0x00), 389 | LIMEGREEN = EGERGB(0x32, 0xCD, 0x32), 390 | LINEN = EGERGB(0xFA, 0xF0, 0xE6), 391 | MAGENTA = EGERGB(0xFF, 0x00, 0xFF), 392 | MAROON = EGERGB(0x80, 0x00, 0x00), 393 | MEDIUMAQUAMARINE = EGERGB(0x66, 0xCD, 0xAA), 394 | MEDIUMBLUE = EGERGB(0x00, 0x00, 0xCD), 395 | MEDIUMORCHID = EGERGB(0xBA, 0x55, 0xD3), 396 | MEDIUMPURPLE = EGERGB(0x93, 0x70, 0xDB), 397 | MEDIUMSEAGREEN = EGERGB(0x3C, 0xB3, 0x71), 398 | MEDIUMSLATEBLUE = EGERGB(0x7B, 0x68, 0xEE), 399 | MEDIUMSPRINGGREEN = EGERGB(0x00, 0xFA, 0x9A), 400 | MEDIUMTURQUOISE = EGERGB(0x48, 0xD1, 0xCC), 401 | MEDIUMVIOLETRED = EGERGB(0xC7, 0x15, 0x85), 402 | MIDNIGHTBLUE = EGERGB(0x19, 0x19, 0x70), 403 | MINTCREAM = EGERGB(0xF5, 0xFF, 0xFA), 404 | MISTYROSE = EGERGB(0xFF, 0xE4, 0xE1), 405 | MOCCASIN = EGERGB(0xFF, 0xE4, 0xB5), 406 | NAVAJOWHITE = EGERGB(0xFF, 0xDE, 0xAD), 407 | NAVY = EGERGB(0x00, 0x00, 0x80), 408 | OLDLACE = EGERGB(0xFD, 0xF5, 0xE6), 409 | OLIVE = EGERGB(0x80, 0x80, 0x00), 410 | OLIVEDRAB = EGERGB(0x6B, 0x8E, 0x23), 411 | ORANGE = EGERGB(0xFF, 0xA5, 0x00), 412 | ORANGERED = EGERGB(0xFF, 0x45, 0x00), 413 | ORCHID = EGERGB(0xDA, 0x70, 0xD6), 414 | PALEGOLDENROD = EGERGB(0xEE, 0xE8, 0xAA), 415 | PALEGREEN = EGERGB(0x98, 0xFB, 0x98), 416 | PALETURQUOISE = EGERGB(0xAF, 0xEE, 0xEE), 417 | PALEVIOLETRED = EGERGB(0xDB, 0x70, 0x93), 418 | PAPAYAWHIP = EGERGB(0xFF, 0xEF, 0xD5), 419 | PEACHPUFF = EGERGB(0xFF, 0xDA, 0xB9), 420 | PERU = EGERGB(0xCD, 0x85, 0x3F), 421 | PINK = EGERGB(0xFF, 0xC0, 0xCB), 422 | PLUM = EGERGB(0xDD, 0xA0, 0xDD), 423 | POWDERBLUE = EGERGB(0xB0, 0xE0, 0xE6), 424 | PURPLE = EGERGB(0x80, 0x00, 0x80), 425 | RED = EGERGB(0xFF, 0x00, 0x00), 426 | ROSYBROWN = EGERGB(0xBC, 0x8F, 0x8F), 427 | ROYALBLUE = EGERGB(0x41, 0x69, 0xE1), 428 | SADDLEBROWN = EGERGB(0x8B, 0x45, 0x13), 429 | SALMON = EGERGB(0xFA, 0x80, 0x72), 430 | SANDYBROWN = EGERGB(0xF4, 0xA4, 0x60), 431 | SEAGREEN = EGERGB(0x2E, 0x8B, 0x57), 432 | SEASHELL = EGERGB(0xFF, 0xF5, 0xEE), 433 | SIENNA = EGERGB(0xA0, 0x52, 0x2D), 434 | SILVER = EGERGB(0xC0, 0xC0, 0xC0), 435 | SKYBLUE = EGERGB(0x87, 0xCE, 0xEB), 436 | SLATEBLUE = EGERGB(0x6A, 0x5A, 0xCD), 437 | SLATEGRAY = EGERGB(0x70, 0x80, 0x90), 438 | SNOW = EGERGB(0xFF, 0xFA, 0xFA), 439 | SPRINGGREEN = EGERGB(0x00, 0xFF, 0x7F), 440 | STEELBLUE = EGERGB(0x46, 0x82, 0xB4), 441 | TAN = EGERGB(0xD2, 0xB4, 0x8C), 442 | TEAL = EGERGB(0x00, 0x80, 0x80), 443 | THISTLE = EGERGB(0xD8, 0xBF, 0xD8), 444 | TOMATO = EGERGB(0xFF, 0x63, 0x47), 445 | TURQUOISE = EGERGB(0x40, 0xE0, 0xD0), 446 | VIOLET = EGERGB(0xEE, 0x82, 0xEE), 447 | WHEAT = EGERGB(0xF5, 0xDE, 0xB3), 448 | WHITE = EGERGB(0xFF, 0xFF, 0xFF), 449 | WHITESMOKE = EGERGB(0xF5, 0xF5, 0xF5), 450 | YELLOW = EGERGB(0xFF, 0xFF, 0x00), 451 | YELLOWGREEN = EGERGB(0x9A, 0xCD, 0x32), 452 | }; 453 | 454 | /* Line styles for get/setlinestyle */ 455 | enum line_styles 456 | { 457 | SOLID_LINE = PS_SOLID, 458 | CENTER_LINE = PS_DASH, 459 | DOTTED_LINE = PS_DOT, 460 | DASHED_LINE = PS_DASHDOT, 461 | NULL_LINE = PS_NULL, 462 | USERBIT_LINE = PS_USERSTYLE, /* User defined line style */ 463 | }; 464 | 465 | struct line_style_type 466 | { 467 | int linestyle; 468 | unsigned short upattern; 469 | int thickness; 470 | }; 471 | 472 | enum line_cap_type 473 | { 474 | LINECAP_FLAT = 0, 475 | LINECAP_SQUARE, 476 | LINECAP_ROUND, 477 | }; 478 | 479 | enum line_join_type 480 | { 481 | LINEJOIN_MITER = 0, 482 | LINEJOIN_BEVEL, 483 | LINEJOIN_ROUND, 484 | }; 485 | 486 | /* Fill patterns for get/set fillstyle */ 487 | enum fill_patterns 488 | { 489 | EMPTY_FILL, /* fills area in background color */ 490 | SOLID_FILL, /* fills area in solid fill color */ 491 | LINE_FILL, /* --- fill */ 492 | LTSLASH_FILL, /* /// fill */ 493 | SLASH_FILL, /* /// fill with thick lines */ 494 | BKSLASH_FILL, /* \\\ fill with thick lines */ 495 | LTBKSLASH_FILL, /* \\\ fill */ 496 | HATCH_FILL, /* light hatch fill */ 497 | XHATCH_FILL, /* heavy cross hatch fill */ 498 | INTERLEAVE_FILL, /* interleaving line fill */ 499 | WIDE_DOT_FILL, /* Widely spaced dot fill */ 500 | CLOSE_DOT_FILL, /* Closely spaced dot fill */ 501 | USER_FILL /* user defined fill */ 502 | }; 503 | 504 | enum fill_mode 505 | { 506 | FILLMODE_DEFAULT = 0, 507 | FILLMODE_ALTERNATE = 1, 508 | FILLMODE_WINDING = 2, 509 | }; 510 | 511 | /* Horizontal and vertical justification for settextjustify */ 512 | enum text_just 513 | { 514 | LEFT_TEXT = 0, 515 | CENTER_TEXT = 1, 516 | RIGHT_TEXT = 2, 517 | 518 | TOP_TEXT = 0, 519 | /* CENTER_TEXT = 1, already defined above */ 520 | BOTTOM_TEXT = 2 521 | }; 522 | 523 | struct textsettingstype 524 | { 525 | int font; 526 | int direction; 527 | int charsize; 528 | int horiz; 529 | int vert; 530 | }; 531 | 532 | enum font_styles 533 | { 534 | FONTSTYLE_BOLD = 1, 535 | FONTSTYLE_ITALIC = 2, 536 | FONTSTYLE_UNDERLINE = 4, 537 | FONTSTYLE_STRIKEOUT = 8, 538 | }; 539 | 540 | enum music_state_flag 541 | { 542 | MUSIC_MODE_NOT_OPEN = 0x0, 543 | MUSIC_MODE_NOT_READY = 0x20C, 544 | MUSIC_MODE_PAUSE = 0x211, 545 | MUSIC_MODE_PLAY = 0x20E, 546 | MUSIC_MODE_STOP = 0x20D, 547 | MUSIC_MODE_OPEN = 0x212, 548 | MUSIC_MODE_SEEK = 0x210, 549 | }; 550 | 551 | #define MUSIC_ERROR 0xFFFFFFFF 552 | 553 | enum key_msg_flag 554 | { 555 | KEYMSG_CHAR_FLAG = 2, 556 | KEYMSG_DOWN_FLAG = 1, 557 | KEYMSG_UP_FLAG = 1, 558 | 559 | KEYMSG_CHAR = 0x40000, 560 | KEYMSG_DOWN = 0x10000, 561 | KEYMSG_UP = 0x20000, 562 | KEYMSG_FIRSTDOWN = 0x80000, 563 | }; 564 | 565 | enum key_code_e 566 | { 567 | key_mouse_l = 0x01, 568 | key_mouse_r = 0x02, 569 | key_mouse_m = 0x04, 570 | key_back = 0x08, 571 | key_tab = 0x09, 572 | key_enter = 0x0d, 573 | key_shift = 0x10, 574 | key_control = 0x11, 575 | key_menu = 0x12, 576 | key_pause = 0x13, 577 | key_capslock = 0x14, 578 | key_esc = 0x1b, 579 | key_space = 0x20, 580 | 581 | key_pageup = 0x21, 582 | key_pagedown = 0x22, 583 | key_end = 0x23, 584 | key_home = 0x24, 585 | 586 | key_left = 0x25, 587 | key_up = 0x26, 588 | key_right = 0x27, 589 | key_down = 0x28, 590 | 591 | key_print = 0x2a, 592 | key_snapshot = 0x2c, 593 | key_insert = 0x2d, 594 | key_delete = 0x2e, 595 | 596 | key_0 = 0x30, 597 | key_1 = 0x31, 598 | key_2 = 0x32, 599 | key_3 = 0x33, 600 | key_4 = 0x34, 601 | key_5 = 0x35, 602 | key_6 = 0x36, 603 | key_7 = 0x37, 604 | key_8 = 0x38, 605 | key_9 = 0x39, 606 | 607 | key_A = 0x41, 608 | key_B = 0x42, 609 | key_C = 0x43, 610 | key_D = 0x44, 611 | key_E = 0x45, 612 | key_F = 0x46, 613 | key_G = 0x47, 614 | key_H = 0x48, 615 | key_I = 0x49, 616 | key_J = 0x4a, 617 | key_K = 0x4b, 618 | key_L = 0x4c, 619 | key_M = 0x4d, 620 | key_N = 0x4e, 621 | key_O = 0x4f, 622 | key_P = 0x50, 623 | key_Q = 0x51, 624 | key_R = 0x52, 625 | key_S = 0x53, 626 | key_T = 0x54, 627 | key_U = 0x55, 628 | key_V = 0x56, 629 | key_W = 0x57, 630 | key_X = 0x58, 631 | key_Y = 0x59, 632 | key_Z = 0x5a, 633 | key_win_l = 0x5b, 634 | key_win_r = 0x5c, 635 | 636 | key_sleep = 0x5f, 637 | 638 | key_num0 = 0x60, 639 | key_num1 = 0x61, 640 | key_num2 = 0x62, 641 | key_num3 = 0x63, 642 | key_num4 = 0x64, 643 | key_num5 = 0x65, 644 | key_num6 = 0x66, 645 | key_num7 = 0x67, 646 | key_num8 = 0x68, 647 | key_num9 = 0x69, 648 | 649 | key_multiply = 0x6a, 650 | key_add = 0x6b, 651 | key_separator = 0x6c, 652 | key_subtract = 0x6d, 653 | key_decimal = 0x6e, 654 | key_divide = 0x6f, 655 | 656 | key_f1 = 0x70, 657 | key_f2 = 0x71, 658 | key_f3 = 0x72, 659 | key_f4 = 0x73, 660 | key_f5 = 0x74, 661 | key_f6 = 0x75, 662 | key_f7 = 0x76, 663 | key_f8 = 0x77, 664 | key_f9 = 0x78, 665 | key_f10 = 0x79, 666 | key_f11 = 0x7a, 667 | key_f12 = 0x7b, 668 | 669 | key_numlock = 0x90, 670 | key_scrolllock = 0x91, 671 | 672 | key_shift_l = 0xa0, 673 | key_shift_r = 0xa1, 674 | key_control_l = 0xa2, 675 | key_control_r = 0xa3, 676 | key_menu_l = 0xa4, 677 | key_menu_r = 0xa5, 678 | 679 | key_semicolon = 0xba, 680 | key_plus = 0xbb, 681 | key_comma = 0xbc, 682 | key_minus = 0xbd, 683 | key_period = 0xbe, 684 | key_slash = 0xbf, 685 | key_tilde = 0xc0, 686 | key_lbrace = 0xdb, 687 | key_backslash = 0xdc, 688 | key_rbrace = 0xdd, 689 | key_quote = 0xde, 690 | 691 | key_ime_process = 0xe5, 692 | }; 693 | 694 | enum key_msg_e 695 | { 696 | key_msg_down = 1, 697 | key_msg_up = 2, 698 | key_msg_char = 4, 699 | }; 700 | 701 | enum key_flag_e 702 | { 703 | key_flag_shift = 0x100, 704 | key_flag_ctrl = 0x200, 705 | key_flag_first_down = 0x80000, 706 | }; 707 | 708 | struct key_msg 709 | { 710 | int key; 711 | key_msg_e msg; 712 | unsigned int flags; 713 | }; 714 | 715 | enum mouse_msg_e 716 | { 717 | mouse_msg_down = 0x10, 718 | mouse_msg_up = 0x20, 719 | mouse_msg_move = 0x40, 720 | mouse_msg_wheel = 0x80, 721 | }; 722 | 723 | enum mouse_flag_e 724 | { 725 | mouse_flag_left = 1, 726 | mouse_flag_right = 2, 727 | mouse_flag_mid = 4, 728 | mouse_flag_shift = 0x100, 729 | mouse_flag_ctrl = 0x200, 730 | }; 731 | 732 | struct mouse_msg 733 | { 734 | int x; 735 | int y; 736 | mouse_msg_e msg; 737 | unsigned int flags; 738 | int wheel; 739 | bool is_left() const {return (flags & mouse_flag_left) != 0;} 740 | bool is_right() const {return (flags & mouse_flag_right) != 0;} 741 | bool is_mid() const {return (flags & mouse_flag_mid) != 0;} 742 | bool is_down() const {return msg == mouse_msg_down;} 743 | bool is_up() const {return msg == mouse_msg_up;} 744 | bool is_move() const {return msg == mouse_msg_move;} 745 | bool is_wheel() const {return msg == mouse_msg_wheel;} 746 | }; 747 | 748 | struct MOUSEMSG 749 | { 750 | UINT uMsg; 751 | bool mkCtrl; 752 | bool mkShift; 753 | bool mkLButton; 754 | bool mkMButton; 755 | bool mkRButton; 756 | short x; 757 | short y; 758 | short wheel; 759 | }; 760 | 761 | struct viewporttype 762 | { 763 | int left; 764 | int top; 765 | int right; 766 | int bottom; 767 | int clipflag; 768 | }; 769 | 770 | // matrix for transformation 771 | struct ege_transform_matrix 772 | { 773 | float m11, m12; 774 | float m21, m22; 775 | float m31, m32; 776 | }; 777 | 778 | struct ege_path 779 | { 780 | private: 781 | void* m_data; 782 | 783 | public: 784 | ege_path(); 785 | ege_path(const ege_point* points, const unsigned char* types, int count); 786 | ege_path(const ege_path& path); 787 | virtual ~ege_path(); 788 | 789 | const void* data() const; 790 | void* data(); 791 | ege_path& operator=(const ege_path& path); 792 | }; 793 | 794 | struct msg_createwindow 795 | { 796 | HANDLE hEvent; 797 | HWND hwnd; 798 | const wchar_t* classname; 799 | DWORD style; 800 | DWORD exstyle; 801 | size_t id; 802 | LPVOID param; 803 | }; 804 | 805 | typedef void (CALLBACK_PROC)(); 806 | typedef int (__stdcall MSG_KEY_PROC )(void*, unsigned, int); 807 | typedef int (__stdcall MSG_MOUSE_PROC)(void*, unsigned, int, int, int); 808 | typedef CALLBACK_PROC * LPCALLBACK_PROC; 809 | typedef MSG_KEY_PROC * LPMSG_KEY_PROC; 810 | typedef MSG_MOUSE_PROC * LPMSG_MOUSE_PROC; 811 | 812 | struct VECTOR3D; 813 | 814 | void EGEAPI rotate_point3d_x(VECTOR3D* point, float rad); 815 | void EGEAPI rotate_point3d_y(VECTOR3D* point, float rad); 816 | void EGEAPI rotate_point3d_z(VECTOR3D* point, float rad); 817 | 818 | struct VECTOR3D 819 | { 820 | float x, y, z; 821 | 822 | VECTOR3D() : x(0.0f), y(0.0f), z(0.0f) {} 823 | VECTOR3D(float x, float y, float z = 0.0f) : x(x), y(y), z(z) {} 824 | 825 | VECTOR3D& operator=(const VECTOR3D& vector) 826 | { 827 | x = vector.x; 828 | y = vector.y; 829 | z = vector.z; 830 | return *this; 831 | } 832 | 833 | VECTOR3D& operator+=(const VECTOR3D& vector); 834 | VECTOR3D& operator-=(const VECTOR3D& vector); 835 | VECTOR3D operator+ (const VECTOR3D& vector) const; 836 | VECTOR3D operator- (const VECTOR3D& vector) const; 837 | VECTOR3D& operator*=(float scale); 838 | VECTOR3D operator* (float scale) const; 839 | float operator* (const VECTOR3D& vector) const; 840 | VECTOR3D operator& (const VECTOR3D& vector) const; 841 | VECTOR3D& operator&=(const VECTOR3D& vector); 842 | float GetModule() const; 843 | 844 | float GetSqrModule() const { return float(x * x + y * y + z * z); } 845 | 846 | VECTOR3D& SetModule(float m) 847 | { 848 | float t = m / GetModule(); 849 | *this *= t; 850 | return *this; 851 | } 852 | 853 | VECTOR3D& Rotate(float rad, const VECTOR3D& vector); 854 | 855 | VECTOR3D& Rotate(float rad, float x, float y, float z) 856 | { 857 | VECTOR3D v(x, y, z); 858 | return Rotate(rad, v); 859 | } 860 | 861 | VECTOR3D& Rotate (const VECTOR3D& e, const VECTOR3D& s = VECTOR3D(0.0f, 0.0f, 1.0f)); 862 | static float GetAngle(const VECTOR3D& e, const VECTOR3D& s = VECTOR3D(0.0f, 0.0f, 1.0f)); 863 | }; 864 | 865 | class IMAGE; 866 | typedef IMAGE *PIMAGE; 867 | typedef const IMAGE *PCIMAGE; 868 | 869 | // `codepage` should be `EGE_CODEPAGE_XXX`, default is `EGE_CODEPAGE_ANSI`. 870 | void EGEAPI setcodepage(unsigned int codepage); 871 | unsigned int EGEAPI getcodepage(); 872 | // set whether char message of `getkey()` use UTF-16 873 | void EGEAPI setunicodecharmessage(bool enable); 874 | bool EGEAPI getunicodecharmessage(); 875 | void EGEAPI setinitmode(int mode, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT); 876 | int EGEAPI getinitmode(); 877 | void EGEAPI initgraph(int width, int height, int mode); 878 | 879 | inline void EGEAPI initgraph(int width, int height) 880 | { 881 | #if !defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) 882 | initgraph(width, height, getinitmode()); 883 | #else 884 | initgraph(width, height, getinitmode() | INIT_WITHLOGO); 885 | #endif 886 | } 887 | 888 | void EGEAPI initgraph(int* gdriver, int* gmode, const char* path); 889 | void EGEAPI closegraph(); 890 | bool EGEAPI is_run(); 891 | void EGEAPI setcaption(const char* caption); 892 | void EGEAPI setcaption(const wchar_t* caption); 893 | void EGEAPI seticon(int icon_id); 894 | int EGEAPI attachHWND(HWND hWnd); 895 | 896 | void EGEAPI showwindow(); 897 | void EGEAPI hidewindow(); 898 | void EGEAPI movewindow(int x, int y, bool redraw = true); 899 | void EGEAPI resizewindow(int width, int height); 900 | void EGEAPI flushwindow(); 901 | 902 | void EGEAPI setrendermode(rendermode_e mode); 903 | 904 | PIMAGE gettarget(); 905 | int settarget(PIMAGE pbuf); 906 | 907 | void EGEAPI cleardevice(PIMAGE pimg = NULL); 908 | 909 | void EGEAPI getviewport(int* left, int* top, int* right, int* bottom, int* clip = 0, PCIMAGE pimg = NULL); 910 | void EGEAPI setviewport(int left, int top, int right, int bottom, int clip = 1, PIMAGE pimg = NULL); 911 | void EGEAPI clearviewport(PIMAGE pimg = NULL); 912 | 913 | EGE_DEPRECATE(setactivepage, "Please use the image function instead.") 914 | void EGEAPI setactivepage(int page); 915 | EGE_DEPRECATE(setvisualpage, "Please use the image function instead.") 916 | void EGEAPI setvisualpage(int page); 917 | EGE_DEPRECATE(swappage, "Please use the image function instead.") 918 | void EGEAPI swappage(); 919 | void EGEAPI window_getviewport(viewporttype * viewport); 920 | void EGEAPI window_getviewport(int* left, int* top, int* right, int* bottom); 921 | void EGEAPI window_setviewport(int left, int top, int right, int bottom); 922 | 923 | 924 | void EGEAPI getlinestyle(int* linestyle, unsigned short* pattern = NULL, int* thickness = NULL, PCIMAGE pimg = NULL); 925 | void EGEAPI setlinestyle(int linestyle, unsigned short pattern = 0, int thickness = 1, PIMAGE pimg = NULL); 926 | void EGEAPI setlinewidth(float width, PIMAGE pimg = NULL); 927 | 928 | void EGEAPI setlinecap(line_cap_type linecap, PIMAGE pimg = NULL); 929 | void EGEAPI setlinecap(line_cap_type startCap, line_cap_type endCap, PIMAGE pimg = NULL); 930 | void EGEAPI getlinecap(line_cap_type* startCap, line_cap_type* endCap, PIMAGE pimg = NULL); 931 | line_cap_type EGEAPI getlinecap(PIMAGE pimg = NULL); 932 | 933 | void EGEAPI setlinejoin(line_join_type linejoin, PIMAGE pimg = NULL); 934 | void EGEAPI setlinejoin(line_join_type linejoin, float miterLimit, PIMAGE pimg = NULL); 935 | void EGEAPI getlinejoin(line_join_type* linejoin, float* miterLimit, PIMAGE pimg = NULL); 936 | line_join_type EGEAPI getlinejoin(PIMAGE pimg = NULL); 937 | 938 | //void getfillstyle(color_t *pcolor, int *ppattern = NULL, PIMAGE pimg = NULL); // ### 939 | void EGEAPI setfillstyle(int pattern, color_t color, PIMAGE pimg = NULL); 940 | 941 | void EGEAPI setwritemode(int mode, PIMAGE pimg = NULL); 942 | 943 | //void EGEAPI graphdefaults(PIMAGE pimg = NULL); // ### 944 | 945 | color_t EGEAPI getcolor (PCIMAGE pimg = NULL); 946 | color_t EGEAPI getlinecolor (PCIMAGE pimg = NULL); 947 | color_t EGEAPI getfillcolor (PCIMAGE pimg = NULL); 948 | color_t EGEAPI getbkcolor (PCIMAGE pimg = NULL); 949 | color_t EGEAPI gettextcolor (PCIMAGE pimg = NULL); 950 | 951 | void EGEAPI setcolor (color_t color, PIMAGE pimg = NULL); 952 | void EGEAPI setlinecolor (color_t color, PIMAGE pimg = NULL); 953 | void EGEAPI setfillcolor (color_t color, PIMAGE pimg = NULL); 954 | void EGEAPI setbkcolor (color_t color, PIMAGE pimg = NULL); 955 | void EGEAPI setbkcolor_f (color_t color, PIMAGE pimg = NULL); 956 | void EGEAPI settextcolor (color_t color, PIMAGE pimg = NULL); 957 | void EGEAPI setfontbkcolor(color_t color, PIMAGE pimg = NULL); 958 | 959 | void EGEAPI setbkmode(int bkMode, PIMAGE pimg = NULL); 960 | 961 | #define RGBtoGRAY rgb2gray 962 | #define RGBtoHSL rgb2hsl 963 | #define RGBtoHSV rgb2hsv 964 | #define HSLtoRGB hsl2rgb 965 | #define HSVtoRGB hsv2rgb 966 | 967 | color_t EGEAPI rgb2gray(color_t rgb); 968 | void EGEAPI rgb2hsl(color_t rgb, float* H, float* S, float* L); 969 | void EGEAPI rgb2hsv(color_t rgb, float* H, float* S, float* V); 970 | color_t EGEAPI hsl2rgb(float H, float S, float L); 971 | color_t EGEAPI hsv2rgb(float H, float S, float V); 972 | 973 | color_t EGEAPI colorblend (color_t dst, color_t src, unsigned char alpha); 974 | color_t EGEAPI colorblend_f(color_t dst, color_t src, unsigned char alpha); 975 | color_t EGEAPI alphablend (color_t dst, color_t src); 976 | color_t EGEAPI alphablend (color_t dst, color_t src, unsigned char srcAlphaFactor); 977 | color_t EGEAPI alphablend_premultiplied(color_t dst, color_t src); 978 | color_t EGEAPI alphablend_premultiplied(color_t dst, color_t src, unsigned char srcAlphaFactor); 979 | 980 | color_t EGEAPI getpixel (int x, int y, PCIMAGE pimg = NULL); 981 | void EGEAPI putpixel (int x, int y, color_t color, PIMAGE pimg = NULL); 982 | color_t EGEAPI getpixel_f (int x, int y, PCIMAGE pimg = NULL); 983 | void EGEAPI putpixel_f (int x, int y, color_t color, PIMAGE pimg = NULL); 984 | void EGEAPI putpixels (int numOfPoints, const int* points, PIMAGE pimg = NULL); 985 | void EGEAPI putpixels_f(int numOfPoints, const int* points, PIMAGE pimg = NULL); 986 | 987 | void EGEAPI putpixel_withalpha (int x, int y, color_t color, PIMAGE pimg = NULL); 988 | void EGEAPI putpixel_withalpha_f (int x, int y, color_t color, PIMAGE pimg = NULL); 989 | void EGEAPI putpixel_savealpha (int x, int y, color_t color, PIMAGE pimg = NULL); 990 | void EGEAPI putpixel_savealpha_f (int x, int y, color_t color, PIMAGE pimg = NULL); 991 | void EGEAPI putpixel_alphablend (int x, int y, color_t color, PIMAGE pimg = NULL); 992 | void EGEAPI putpixel_alphablend_f(int x, int y, color_t color, PIMAGE pimg = NULL); 993 | void EGEAPI putpixel_alphablend (int x, int y, color_t color, unsigned char alphaFactor, PIMAGE pimg = NULL); 994 | void EGEAPI putpixel_alphablend_f(int x, int y, color_t color, unsigned char alphaFactor, PIMAGE pimg = NULL); 995 | 996 | void EGEAPI moveto (int x, int y, PIMAGE pimg = NULL); 997 | void EGEAPI moverel(int dx, int dy, PIMAGE pimg = NULL); 998 | 999 | void EGEAPI line (int x1, int y1, int x2, int y2, PIMAGE pimg = NULL); 1000 | void EGEAPI line_f (float x1, float y1, float x2, float y2, PIMAGE pimg = NULL); 1001 | void EGEAPI lineto (int x, int y, PIMAGE pimg = NULL); 1002 | void EGEAPI lineto_f (float x, float y, PIMAGE pimg = NULL); 1003 | void EGEAPI linerel (int dx, int dy, PIMAGE pimg = NULL); 1004 | void EGEAPI linerel_f(float dx, float dy, PIMAGE pimg = NULL); 1005 | 1006 | //void EGEAPI getarccoords(int *px, int *py, int *pxstart, int *pystart, int *pxend, int *pyend, PIMAGE pimg = NULL); // ### 1007 | 1008 | void EGEAPI ellipse (int x, int y, int startAngle, int endAngle, int xRadius, int yRadius, PIMAGE pimg = NULL); 1009 | void EGEAPI ellipsef (float x, float y, float startAngle, float endAngle, float xRadius, float yRadius, PIMAGE pimg = NULL); 1010 | void EGEAPI sector (int x, int y, int startAngle, int endAngle, int xRadius, int yRadius, PIMAGE pimg = NULL); 1011 | void EGEAPI sectorf (float x, float y, float startAngle, float endAngle, float xRadius, float yRadius, PIMAGE pimg = NULL); 1012 | void EGEAPI pie (int x, int y, int startAngle, int endAngle, int xRadius, int yRadius, PIMAGE pimg = NULL); 1013 | void EGEAPI pief (float x, float y, float startAngle, float endAngle, float xRadius, float yRadius, PIMAGE pimg = NULL); 1014 | void EGEAPI fillpie (int x, int y, int startAngle, int endAngle, int xRadius, int yRadius, PIMAGE pimg = NULL); 1015 | void EGEAPI fillpief (float x, float y, float startAngle, float endAngle, float xRadius, float yRadius, PIMAGE pimg = NULL); 1016 | void EGEAPI solidpie (int x, int y, int startAngle, int endAngle, int xRadius, int yRadius, PIMAGE pimg = NULL); 1017 | void EGEAPI solidpief (float x, float y, float startAngle, float endAngle, float xRadius, float yRadius, PIMAGE pimg = NULL); 1018 | 1019 | void EGEAPI arc (int x, int y, int startAngle, int endAngle, int radius, PIMAGE pimg = NULL); 1020 | void EGEAPI arcf (float x, float y, float startAngle, float endAngle, float radius, PIMAGE pimg = NULL); 1021 | void EGEAPI pieslice (int x, int y, int startAngle, int endAngle, int radius, PIMAGE pimg = NULL); 1022 | void EGEAPI pieslicef (float x, float y, float startAngle, float endAngle, float radius, PIMAGE pimg = NULL); 1023 | 1024 | void EGEAPI fillellipse (int x, int y, int xRadius, int yRadius, PIMAGE pimg = NULL); 1025 | void EGEAPI fillellipsef (float x, float y, float xRadius, float yRadius, PIMAGE pimg = NULL); 1026 | void EGEAPI solidellipse (int x, int y, int xRadius, int yRadius, PIMAGE pimg = NULL); 1027 | void EGEAPI solidellipsef(float x, float y, float xRadius, float yRadius, PIMAGE pimg = NULL); 1028 | 1029 | void EGEAPI circle (int x, int y, int radius, PIMAGE pimg = NULL); 1030 | void EGEAPI circlef (float x, float y, float radius, PIMAGE pimg = NULL); 1031 | void EGEAPI fillcircle (int x, int y, int radius, PIMAGE pimg = NULL); 1032 | void EGEAPI fillcirclef (float x, float y, float radius, PIMAGE pimg = NULL); 1033 | void EGEAPI solidcircle (int x, int y, int radius, PIMAGE pimg = NULL); 1034 | void EGEAPI solidcirclef (float x, float y, float radius, PIMAGE pimg = NULL); 1035 | 1036 | void EGEAPI bar3d (int left, int top, int right, int bottom, int depth, int topFlag, PIMAGE pimg = NULL); 1037 | void EGEAPI bar (int left, int top, int right, int bottom, PIMAGE pimg = NULL); 1038 | void EGEAPI rectangle (int left, int top, int right, int bottom, PIMAGE pimg = NULL); 1039 | void EGEAPI fillrect (int left, int top, int right, int bottom, PIMAGE pimg = NULL); 1040 | void EGEAPI solidrect (int left, int top, int right, int bottom, PIMAGE pimg = NULL); 1041 | 1042 | void EGEAPI roundrect (int left, int top, int right, int bottom, int radius, PIMAGE pimg = NULL); 1043 | void EGEAPI fillroundrect (int left, int top, int right, int bottom, int radius, PIMAGE pimg = NULL); 1044 | void EGEAPI solidroundrect(int left, int top, int right, int bottom, int radius, PIMAGE pimg = NULL); 1045 | 1046 | void EGEAPI roundrect (int left, int top, int right, int bottom, int xRadius, int yRadius, PIMAGE pimg = NULL); 1047 | void EGEAPI fillroundrect (int left, int top, int right, int bottom, int xRadius, int yRadius, PIMAGE pimg = NULL); 1048 | void EGEAPI solidroundrect(int left, int top, int right, int bottom, int xRadius, int yRadius, PIMAGE pimg = NULL); 1049 | 1050 | void EGEAPI drawpoly (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1051 | void EGEAPI polyline (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1052 | void EGEAPI polygon (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1053 | void EGEAPI fillpoly (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1054 | void EGEAPI solidpoly (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1055 | void EGEAPI fillpoly_gradient(int numOfPoints, const ege_colpoint* points, PIMAGE pimg = NULL); 1056 | 1057 | void EGEAPI drawlines (int numOfLines, const int *points, PIMAGE pimg = NULL); 1058 | void EGEAPI drawbezier (int numOfPoints, const int *points, PIMAGE pimg = NULL); 1059 | 1060 | void EGEAPI floodfill (int x, int y, int borderColor, PIMAGE pimg = NULL); 1061 | void EGEAPI floodfillsurface (int x, int y, color_t areaColor, PIMAGE pimg = NULL); 1062 | 1063 | #ifdef EGE_GDIPLUS 1064 | 1065 | void EGEAPI ege_enable_aa(bool enable, PIMAGE pimg = NULL); 1066 | 1067 | void EGEAPI ege_setalpha(int alpha, PIMAGE pimg = NULL); 1068 | 1069 | void EGEAPI ege_line(float x1, float y1, float x2, float y2, PIMAGE pimg = NULL); 1070 | 1071 | void EGEAPI ege_drawpoly (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1072 | void EGEAPI ege_polyline (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1073 | void EGEAPI ege_polygon (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1074 | void EGEAPI ege_fillpoly (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1075 | 1076 | void EGEAPI ege_bezier (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1077 | void EGEAPI ege_drawbezier (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); // Same as ege_bezier 1078 | 1079 | void EGEAPI ege_drawcurve (int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1080 | void EGEAPI ege_drawclosedcurve(int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1081 | void EGEAPI ege_fillclosedcurve(int numOfPoints, const ege_point* points, PIMAGE pimg = NULL); 1082 | void EGEAPI ege_drawcurve (int numOfPoints, const ege_point* points, float tension, PIMAGE pimg = NULL); 1083 | void EGEAPI ege_drawclosedcurve(int numOfPoints, const ege_point* points, float tension, PIMAGE pimg = NULL); 1084 | void EGEAPI ege_fillclosedcurve(int numOfPoints, const ege_point* points, float tension, PIMAGE pimg = NULL); 1085 | 1086 | void EGEAPI ege_rectangle (float x, float y, float w, float h, PIMAGE pimg = NULL); 1087 | void EGEAPI ege_fillrect (float x, float y, float w, float h, PIMAGE pimg = NULL); 1088 | 1089 | void EGEAPI ege_circle (float x, float y, float radius, PIMAGE pimg = NULL); 1090 | void EGEAPI ege_fillcircle (float x, float y, float radius, PIMAGE pimg = NULL); 1091 | 1092 | void EGEAPI ege_ellipse (float x, float y, float w, float h, PIMAGE pimg = NULL); 1093 | void EGEAPI ege_fillellipse (float x, float y, float w, float h, PIMAGE pimg = NULL); 1094 | void EGEAPI ege_arc (float x, float y, float w, float h, float startAngle, float sweepAngle, PIMAGE pimg = NULL); 1095 | void EGEAPI ege_pie (float x, float y, float w, float h, float startAngle, float sweepAngle, PIMAGE pimg = NULL); 1096 | void EGEAPI ege_fillpie (float x, float y, float w, float h, float startAngle, float sweepAngle, PIMAGE pimg = NULL); 1097 | 1098 | void EGEAPI ege_roundrect (float x, float y, float w, float h, float radius, PIMAGE pimg = NULL); 1099 | void EGEAPI ege_fillroundrect(float x, float y, float w, float h, float radius, PIMAGE pimg = NULL); 1100 | void EGEAPI ege_roundrect (float x, float y, float w, float h, float radius1, float radius2, float radius3, float radius4, PIMAGE pimg = NULL); 1101 | void EGEAPI ege_fillroundrect(float x, float y, float w, float h, float radius1, float radius2, float radius3, float radius4, PIMAGE pimg = NULL); 1102 | 1103 | void EGEAPI ege_setpattern_none(PIMAGE pimg = NULL); 1104 | void EGEAPI ege_setpattern_lineargradient(float x1, float y1, color_t c1, float x2, float y2, color_t c2, PIMAGE pimg = NULL); 1105 | void EGEAPI ege_setpattern_pathgradient(ege_point center, color_t centerColor, int count, const ege_point* points, int colorCount, const color_t* pointColors, PIMAGE pimg = NULL); 1106 | void EGEAPI ege_setpattern_ellipsegradient(ege_point center, color_t centerColor, float x, float y, float w, float h, color_t color, PIMAGE pimg = NULL); 1107 | void EGEAPI ege_setpattern_texture(PIMAGE imgSrc, float x, float y, float w, float h, PIMAGE pimg = NULL); 1108 | 1109 | void EGEAPI ege_drawtext(const char* text, float x, float y, PIMAGE pimg = NULL); 1110 | void EGEAPI ege_drawtext(const wchar_t* text, float x, float y, PIMAGE pimg = NULL); 1111 | 1112 | void EGEAPI ege_gentexture(bool generate, PIMAGE pimg = NULL); 1113 | void EGEAPI ege_puttexture(PCIMAGE imgSrc, float x, float y, float w, float h, PIMAGE pimg = NULL); 1114 | void EGEAPI ege_puttexture(PCIMAGE imgSrc, ege_rect dest, PIMAGE pimg = NULL); 1115 | void EGEAPI ege_puttexture(PCIMAGE imgSrc, ege_rect dest, ege_rect src, PIMAGE pimg = NULL); 1116 | 1117 | //draw image 1118 | void EGEAPI ege_drawimage(PCIMAGE imgSrc,int xDest, int yDest, PIMAGE pimg = NULL); 1119 | void EGEAPI ege_drawimage(PCIMAGE imgSrc,int xDest, int yDest, int widthDest, int heightDest, int xSrc, int ySrc, int widthSrc, int heightSrc,PIMAGE pimg = NULL); 1120 | 1121 | void EGEAPI ege_drawpath(const ege_path* path, PIMAGE pimg = NULL); 1122 | void EGEAPI ege_fillpath(const ege_path* path, PIMAGE pimg = NULL); 1123 | void EGEAPI ege_drawpath(const ege_path* path, float x, float y, PIMAGE pimg = NULL); 1124 | void EGEAPI ege_fillpath(const ege_path* path, float x, float y, PIMAGE pimg = NULL); 1125 | 1126 | ege_path* EGEAPI ege_path_create (); 1127 | ege_path* EGEAPI ege_path_createfrom (const ege_point* points, const unsigned char* types, int count); 1128 | ege_path* EGEAPI ege_path_clone (const ege_path* path); 1129 | void EGEAPI ege_path_destroy (const ege_path* path); 1130 | void EGEAPI ege_path_start (ege_path* path); 1131 | void EGEAPI ege_path_close (ege_path* path); 1132 | void EGEAPI ege_path_closeall (ege_path* path); 1133 | void EGEAPI ege_path_setfillmode(ege_path* path, fill_mode mode); 1134 | 1135 | void EGEAPI ege_path_reset (ege_path* path); 1136 | void EGEAPI ege_path_reverse (ege_path* path); 1137 | void EGEAPI ege_path_widen (ege_path* path, float lineWidth, const ege_transform_matrix* matrix = NULL); 1138 | void EGEAPI ege_path_widen (ege_path* path, float lineWidth, const ege_transform_matrix* matrix, float flatness); 1139 | void EGEAPI ege_path_flatten (ege_path* path, const ege_transform_matrix* matrix = NULL); 1140 | void EGEAPI ege_path_flatten (ege_path* path, const ege_transform_matrix* matrix, float flatness); 1141 | void EGEAPI ege_path_warp (ege_path* path, const ege_point* points, int count, const ege_rect* rect, const ege_transform_matrix* matrix = NULL); 1142 | void EGEAPI ege_path_warp (ege_path* path, const ege_point* points, int count, const ege_rect* rect, const ege_transform_matrix* matrix, float flatness); 1143 | void EGEAPI ege_path_outline (ege_path* path, const ege_transform_matrix* matrix = NULL); 1144 | void EGEAPI ege_path_outline (ege_path* path, const ege_transform_matrix* matrix, float flatness); 1145 | 1146 | bool EGEAPI ege_path_inpath (const ege_path* path, float x, float y); 1147 | bool EGEAPI ege_path_inpath (const ege_path* path, float x, float y, PCIMAGE pimg); 1148 | bool EGEAPI ege_path_instroke (const ege_path* path, float x, float y); 1149 | bool EGEAPI ege_path_instroke (const ege_path* path, float x, float y, PCIMAGE pimg); 1150 | 1151 | ege_point EGEAPI ege_path_lastpoint (const ege_path* path); 1152 | int EGEAPI ege_path_pointcount (const ege_path* path); 1153 | ege_rect EGEAPI ege_path_getbounds (const ege_path* path, const ege_transform_matrix* matrix = NULL); 1154 | ege_rect EGEAPI ege_path_getbounds (const ege_path* path, const ege_transform_matrix* matrix, PCIMAGE pimg); 1155 | ege_point* EGEAPI ege_path_getpathpoints(const ege_path* path, ege_point* points = NULL); 1156 | unsigned char* EGEAPI ege_path_getpathtypes (const ege_path* path, unsigned char* types = NULL); 1157 | 1158 | void EGEAPI ege_path_transform (ege_path* path, const ege_transform_matrix* matrix); 1159 | 1160 | // Adds a non-closed figure to path 1161 | void EGEAPI ege_path_addpath (ege_path* dstPath, const ege_path* srcPath, bool connect); 1162 | void EGEAPI ege_path_addline (ege_path* path, float x1, float y1, float x2, float y2); 1163 | void EGEAPI ege_path_addarc (ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle); 1164 | void EGEAPI ege_path_addpolyline (ege_path* path, int numOfPoints, const ege_point* points); 1165 | void EGEAPI ege_path_addbezier (ege_path* path, int numOfPoints, const ege_point* points); 1166 | void EGEAPI ege_path_addbezier (ege_path* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); 1167 | void EGEAPI ege_path_addcurve (ege_path* path, int numOfPoints, const ege_point* points); 1168 | void EGEAPI ege_path_addcurve (ege_path* path, int numOfPoints, const ege_point* points, float tension); 1169 | 1170 | // Adds a closed figure to path 1171 | void EGEAPI ege_path_addcircle (ege_path* path, float x, float y, float radius); 1172 | void EGEAPI ege_path_addrect (ege_path* path, float x, float y, float width, float height); 1173 | void EGEAPI ege_path_addellipse (ege_path* path, float x, float y, float width, float height); 1174 | void EGEAPI ege_path_addpie (ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle); 1175 | void EGEAPI ege_path_addtext (ege_path* path, float x, float y, const char* text, float height, int length = -1, const char* typeface = NULL, int fontStyle = 0); 1176 | void EGEAPI ege_path_addtext (ege_path* path, float x, float y, const wchar_t* text, float height, int length = -1, const wchar_t* typeface = NULL, int fontStyle = 0); 1177 | void EGEAPI ege_path_addpolygon (ege_path* path, int numOfPoints, const ege_point* points); 1178 | void EGEAPI ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point* points); 1179 | void EGEAPI ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point* points, float tension); 1180 | 1181 | 1182 | // transforms 1183 | void EGEAPI ege_transform_rotate(float angle, PIMAGE pimg = NULL); 1184 | void EGEAPI ege_transform_translate(float x, float y, PIMAGE pimg = NULL); 1185 | void EGEAPI ege_transform_scale(float xScale, float yScale, PIMAGE pimg = NULL); 1186 | void EGEAPI ege_transform_reset(PIMAGE pimg = NULL); 1187 | void EGEAPI ege_get_transform(ege_transform_matrix* matrix, PIMAGE pimg = NULL); 1188 | void EGEAPI ege_set_transform(const ege_transform_matrix* matrix, PIMAGE pimg = NULL); 1189 | ege_point EGEAPI ege_transform_calc(ege_point p, PIMAGE pimg = NULL); // Calculate transformed coordination of p; 1190 | ege_point EGEAPI ege_transform_calc(float x, float y, PIMAGE pimg = NULL); // Calculate transformed coordination of point(x,y); 1191 | 1192 | 1193 | 1194 | // 1195 | #endif 1196 | 1197 | // It is not supported in VC 6.0. 1198 | #ifndef EGE_COMPILERINFO_VC6 1199 | // Console 1200 | bool init_console(); // Initialize the console 1201 | bool clear_console(); // Clear the console 1202 | bool show_console(); // Show the Console 1203 | bool hide_console(); // Hide the console 1204 | bool close_console(); // Close the console and restore the old STD I/O 1205 | #endif 1206 | 1207 | int getch_console(); // Used instead of the getch() function in 1208 | 1209 | void EGEAPI ege_sleep (long ms); 1210 | void EGEAPI delay (long ms); 1211 | void EGEAPI delay_ms (long ms); 1212 | 1213 | void EGEAPI api_sleep (long ms); 1214 | 1215 | void EGEAPI delay_fps (int fps); 1216 | void EGEAPI delay_fps (long fps); 1217 | void EGEAPI delay_fps (double fps); 1218 | void EGEAPI delay_jfps(int fps); 1219 | void EGEAPI delay_jfps(long fps); 1220 | void EGEAPI delay_jfps(double fps); 1221 | 1222 | 1223 | double EGEAPI fclock(); 1224 | 1225 | 1226 | void EGEAPI outtext(const char* text, PIMAGE pimg = NULL); 1227 | void EGEAPI outtext(const wchar_t* text, PIMAGE pimg = NULL); 1228 | void EGEAPI outtext(char c, PIMAGE pimg = NULL); 1229 | void EGEAPI outtext(wchar_t c, PIMAGE pimg = NULL); 1230 | 1231 | void EGEAPI outtextxy(int x, int y, const char* text, PIMAGE pimg = NULL); 1232 | void EGEAPI outtextxy(int x, int y, const wchar_t* text, PIMAGE pimg = NULL); 1233 | void EGEAPI outtextxy(int x, int y, char c, PIMAGE pimg = NULL); 1234 | void EGEAPI outtextxy(int x, int y, wchar_t c, PIMAGE pimg = NULL); 1235 | void EGEAPI xyprintf (int x, int y, const char* format, ...); 1236 | void EGEAPI xyprintf (int x, int y, const wchar_t* format, ...); 1237 | 1238 | void EGEAPI outtextrect(int x, int y, int w, int h, const char* text, PIMAGE pimg = NULL); 1239 | void EGEAPI outtextrect(int x, int y, int w, int h, const wchar_t* text, PIMAGE pimg = NULL); 1240 | void EGEAPI rectprintf (int x, int y, int w, int h, const char* format, ...); 1241 | void EGEAPI rectprintf (int x, int y, int w, int h, const wchar_t* format, ...); 1242 | 1243 | int EGEAPI textwidth(const char* text, PIMAGE pimg = NULL); 1244 | int EGEAPI textwidth(const wchar_t* text, PIMAGE pimg = NULL); 1245 | int EGEAPI textwidth(char c, PIMAGE pimg = NULL); 1246 | int EGEAPI textwidth(wchar_t c, PIMAGE pimg = NULL); 1247 | 1248 | int EGEAPI textheight(const char* text, PIMAGE pimg = NULL); 1249 | int EGEAPI textheight(const wchar_t* text, PIMAGE pimg = NULL); 1250 | int EGEAPI textheight(char c, PIMAGE pimg = NULL); 1251 | int EGEAPI textheight(wchar_t c, PIMAGE pimg = NULL); 1252 | 1253 | void EGEAPI ege_outtextxy(int x, int y, const char* text, PIMAGE pimg = NULL); 1254 | void EGEAPI ege_outtextxy(int x, int y, const wchar_t* text, PIMAGE pimg = NULL); 1255 | void EGEAPI ege_outtextxy(int x, int y, char c, PIMAGE pimg = NULL); 1256 | void EGEAPI ege_outtextxy(int x, int y, wchar_t c, PIMAGE pimg = NULL); 1257 | void EGEAPI ege_xyprintf (int x, int y, const char* format, ...); 1258 | void EGEAPI ege_xyprintf (int x, int y, const wchar_t* format, ...); 1259 | 1260 | void EGEAPI settextjustify(int horiz, int vert, PIMAGE pimg = NULL); 1261 | 1262 | void EGEAPI setfont(int height, int width, const char* typeface, PIMAGE pimg = NULL); 1263 | void EGEAPI setfont(int height, int width, const wchar_t* typeface, PIMAGE pimg = NULL); 1264 | void EGEAPI setfont(int height, int width, const char* typeface, int escapement, int orientation, 1265 | int weight, bool italic, bool underline, bool strikeOut, PIMAGE pimg = NULL); 1266 | void EGEAPI setfont(int height, int width, const wchar_t* typeface, int escapement, int orientation, 1267 | int weight, bool italic, bool underline, bool strikeOut, PIMAGE pimg = NULL); 1268 | void EGEAPI setfont(int height, int width, const char* typeface, int escapement, int orientation, 1269 | int weight, bool italic, bool underline, bool strikeOut, BYTE charSet, 1270 | BYTE outPrecision, BYTE clipPrecision, BYTE quality, BYTE pitchAndFamily, PIMAGE pimg = NULL); 1271 | void EGEAPI setfont(int height, int width, const wchar_t* typeface, int escapement, int orientation, 1272 | int weight, bool italic, bool underline, bool strikeOut, BYTE charSet, 1273 | BYTE outPrecision, BYTE clipPrecision, BYTE quality, BYTE pitchAndFamily, PIMAGE pimg = NULL); 1274 | 1275 | void EGEAPI setfont(const LOGFONTW *font, PIMAGE pimg = NULL); 1276 | void EGEAPI getfont(LOGFONTW *font, PCIMAGE pimg = NULL); 1277 | 1278 | EGE_DEPRECATE(setfont, "Please use the 'getfont' function with the LOGFONTW* parameter instead.") 1279 | void EGEAPI setfont(const LOGFONTA *font, PIMAGE pimg = NULL); 1280 | EGE_DEPRECATE(getfont, "Please use the 'getfont' function with the LOGFONTW* parameter instead.") 1281 | void EGEAPI getfont(LOGFONTA *font, PCIMAGE pimg = NULL); 1282 | 1283 | #define getmaxx getwidth 1284 | #define getmaxy getheight 1285 | 1286 | int EGEAPI getwidth(PCIMAGE pimg = NULL); 1287 | int EGEAPI getheight(PCIMAGE pimg = NULL); 1288 | int EGEAPI getx(PCIMAGE pimg = NULL); 1289 | int EGEAPI gety(PCIMAGE pimg = NULL); 1290 | 1291 | PIMAGE EGEAPI newimage(); 1292 | PIMAGE EGEAPI newimage(int width, int height); 1293 | void EGEAPI delimage(PCIMAGE pimg); 1294 | color_t* EGEAPI getbuffer(PIMAGE pimg); 1295 | const color_t* EGEAPI getbuffer(PCIMAGE pimg); 1296 | 1297 | int EGEAPI resize_f(PIMAGE pimg, int width, int height); 1298 | int EGEAPI resize (PIMAGE pimg, int width, int height); 1299 | 1300 | int EGEAPI getimage(PIMAGE imgDest, int xSrc, int ySrc, int widthSrc, int heightSrc); 1301 | int EGEAPI getimage(PIMAGE imgDest, PCIMAGE imgSrc, int xSrc, int ySrc, int widthSrc, int heightSrc); 1302 | int EGEAPI getimage(PIMAGE imgDest, const char* imageFile, int zoomWidth = 0, int zoomHeight = 0); 1303 | int EGEAPI getimage(PIMAGE imgDest, const wchar_t* imageFile, int zoomWidth = 0, int zoomHeight = 0); 1304 | int EGEAPI getimage(PIMAGE imgDest, const char* resType, const char* resName, int zoomWidth = 0, int zoomHeight = 0); 1305 | int EGEAPI getimage(PIMAGE imgDest, const wchar_t* resType, const wchar_t* resName, int zoomWidth = 0, int zoomHeight = 0); 1306 | int EGEAPI getimage_pngfile(PIMAGE pimg, const char* filename); 1307 | int EGEAPI getimage_pngfile(PIMAGE pimg, const wchar_t* filename); 1308 | 1309 | void EGEAPI putimage(int x, int y, PCIMAGE pimg, DWORD dwRop = SRCCOPY); 1310 | void EGEAPI putimage(int xDest, int yDest, int widthDest, int heightDest, PCIMAGE imgSrc, int xSrc, int ySrc, DWORD dwRop = SRCCOPY); 1311 | void EGEAPI putimage(int xDest, int yDest, int widthDest, int heightDest, PCIMAGE imgSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD dwRop = SRCCOPY); 1312 | 1313 | void EGEAPI putimage(PIMAGE imgDest, int xDest, int yDest, PCIMAGE imgSrc, DWORD dwRop = SRCCOPY); 1314 | void EGEAPI putimage(PIMAGE imgDest, int xDest, int yDest, int widthDest, int heightDest, PCIMAGE imgSrc, int xSrc, int ySrc, DWORD dwRop = SRCCOPY); 1315 | void EGEAPI putimage(PIMAGE imgDest, int xDest, int yDest, int widthDest, int heightDest, PCIMAGE imgSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD dwRop = SRCCOPY); 1316 | 1317 | int EGEAPI saveimage(PCIMAGE pimg, const char* filename, bool withAlphaChannel = false); 1318 | int EGEAPI saveimage(PCIMAGE pimg, const wchar_t* filename, bool withAlphaChannel = false); 1319 | int EGEAPI savepng (PCIMAGE pimg, const char* filename, bool withAlphaChannel = false); 1320 | int EGEAPI savepng (PCIMAGE pimg, const wchar_t* filename, bool withAlphaChannel = false); 1321 | int EGEAPI savebmp (PCIMAGE pimg, const char* filename, bool withAlphaChannel = false); 1322 | int EGEAPI savebmp (PCIMAGE pimg, const wchar_t* filename, bool withAlphaChannel = false); 1323 | 1324 | int EGEAPI putimage_transparent( 1325 | PIMAGE imgDest, // handle to dest 1326 | PCIMAGE imgSrc, // handle to source 1327 | int xDest, // x-coord of destination upper-left corner 1328 | int yDest, // y-coord of destination upper-left corner 1329 | color_t transparentColor, // color to make transparent 1330 | int xSrc = 0, // x-coord of source upper-left corner 1331 | int ySrc = 0, // y-coord of source upper-left corner 1332 | int widthSrc = 0, // width of source rectangle 1333 | int heightSrc = 0 // height of source rectangle 1334 | ); 1335 | 1336 | int EGEAPI putimage_alphablend( 1337 | PIMAGE imgDest, 1338 | PCIMAGE imgSrc, 1339 | int xDest, 1340 | int yDest, 1341 | unsigned char alpha, 1342 | alpha_type alphaType = ALPHATYPE_STRAIGHT 1343 | ); 1344 | int EGEAPI putimage_alphablend( 1345 | PIMAGE imgDest, 1346 | PCIMAGE imgSrc, 1347 | int xDest, 1348 | int yDest, 1349 | unsigned char alpha, 1350 | int xSrc, 1351 | int ySrc, 1352 | alpha_type alphaType = ALPHATYPE_STRAIGHT 1353 | ); 1354 | int EGEAPI putimage_alphablend( 1355 | PIMAGE imgDest, 1356 | PCIMAGE imgSrc, 1357 | int xDest, 1358 | int yDest, 1359 | unsigned char alpha, 1360 | int xSrc, 1361 | int ySrc, 1362 | int widthSrc, 1363 | int heightSrc, 1364 | alpha_type alphaType = ALPHATYPE_STRAIGHT 1365 | ); 1366 | 1367 | int EGEAPI putimage_alphablend( 1368 | PIMAGE imgDest, 1369 | PCIMAGE imgSrc, 1370 | int xDest, 1371 | int yDest, 1372 | int widthDest, 1373 | int heightDest, 1374 | unsigned char alpha, 1375 | int xSrc, 1376 | int ySrc, 1377 | int widthSrc, 1378 | int heightSrc, 1379 | bool smooth = false, 1380 | alpha_type alphaType = ALPHATYPE_STRAIGHT 1381 | ); 1382 | 1383 | int EGEAPI putimage_alphatransparent( 1384 | PIMAGE imgDest, // handle to dest 1385 | PCIMAGE imgSrc, // handle to source 1386 | int xDest, // x-coord of destination upper-left corner 1387 | int yDest, // y-coord of destination upper-left corner 1388 | color_t transparentColor, // color to make transparent 1389 | unsigned char alpha, // alpha 1390 | int xSrc = 0, // x-coord of source upper-left corner 1391 | int ySrc = 0, // y-coord of source upper-left corner 1392 | int widthSrc = 0, // width of source rectangle 1393 | int heightSrc = 0 // height of source rectangle 1394 | ); 1395 | int EGEAPI putimage_withalpha( 1396 | PIMAGE imgDest, // handle to dest 1397 | PCIMAGE imgSrc, // handle to source 1398 | int xDest, // x-coord of destination upper-left corner 1399 | int yDest, // y-coord of destination upper-left corner 1400 | int xSrc = 0, // x-coord of source upper-left corner 1401 | int ySrc = 0, // y-coord of source upper-left corner 1402 | int widthSrc = 0, // width of source rectangle 1403 | int heightSrc = 0 // height of source rectangle 1404 | ); 1405 | int EGEAPI putimage_withalpha( 1406 | PIMAGE imgDest, // handle to dest 1407 | PCIMAGE imgSrc, // handle to source 1408 | int xDest, // x-coord of destination upper-left corner 1409 | int yDest, // y-coord of destination upper-left corner 1410 | int widthDest, // width of destination rectangle 1411 | int heightDest, // height of destination rectangle 1412 | int xSrc, // x-coord of source upper-left corner 1413 | int ySrc, // y-coord of source upper-left corner 1414 | int widthSrc, // width of source rectangle 1415 | int heightSrc, // height of source rectangle 1416 | bool smooth = false 1417 | ); 1418 | int EGEAPI putimage_alphafilter( 1419 | PIMAGE imgDest, // handle to dest 1420 | PCIMAGE imgSrc, // handle to source 1421 | int xDest, // x-coord of destination upper-left corner 1422 | int yDest, // y-coord of destination upper-left corner 1423 | PCIMAGE imgAlpha, // handle to alpha 1424 | int xSrc, // x-coord of source upper-left corner 1425 | int ySrc, // y-coord of source upper-left corner 1426 | int widthSrc, // width of source rectangle 1427 | int heightSrc // height of source rectangle 1428 | ); 1429 | int EGEAPI imagefilter_blurring ( 1430 | PIMAGE imgDest, 1431 | int intensity, 1432 | int alpha, 1433 | int xDest = 0, 1434 | int yDest = 0, 1435 | int widthDest = 0, 1436 | int heightDest = 0 1437 | ); 1438 | int EGEAPI putimage_rotate( 1439 | PIMAGE imgDest, 1440 | PCIMAGE imgTexture, 1441 | int xDest, 1442 | int yDest, 1443 | float xCenter, 1444 | float yCenter, 1445 | float radian, 1446 | bool transparent = false, // use the transparent channel of the image 1447 | int alpha = -1, // in range[0, 256], alpha== -1 means no alpha 1448 | bool smooth = false 1449 | ); 1450 | 1451 | int EGEAPI putimage_rotatezoom( 1452 | PIMAGE imgDest, 1453 | PCIMAGE imgTexture, 1454 | int xDest, 1455 | int yDest, 1456 | float xCenter, 1457 | float yCenter, 1458 | float radian, 1459 | float zoom, 1460 | bool transparent = false, // use the transparent channel of the image 1461 | int alpha = -1, // in range[0, 256], alpha== -1 means no alpha 1462 | bool smooth = false 1463 | ); 1464 | 1465 | int EGEAPI putimage_rotatetransparent( 1466 | PIMAGE imgDest, /* handle to dest, NULL means the SCREEN */ 1467 | PCIMAGE imgSrc, /* handle to source */ 1468 | int xCenterDest, /* x-coord of rotation center in dest */ 1469 | int yCenterDest, /* y-coord of rotation center in dest */ 1470 | int xCenterSrc, /* x-coord of rotation center in source */ 1471 | int yCenterSrc, /* y-coord of rotation center in source */ 1472 | color_t transparentColor, /* color to make transparent */ 1473 | float radian, /* rotation angle (clockwise, in radian) */ 1474 | float zoom = 1.0f /* zoom factor */ 1475 | ); 1476 | 1477 | int EGEAPI putimage_rotatetransparent( 1478 | PIMAGE imgDest, /* handle to dest, NULL means the SCREEN */ 1479 | PCIMAGE imgSrc, /* handle to source */ 1480 | int xCenterDest, /* x-coord of rotation center in dest */ 1481 | int yCenterDest, /* y-coord of rotation center in dest */ 1482 | int xSrc, /* x-coord of source upper-left corner */ 1483 | int ySrc, /* y-coord of source upper-left corner */ 1484 | int widthSrc, /* width of source rectangle */ 1485 | int heightSrc, /* height of source rectangle */ 1486 | int xCenterSrc, /* x-coord of rotation center in source */ 1487 | int yCenterSrc, /* y-coord of rotation center in source */ 1488 | color_t transparentColor, /* color to make transparent */ 1489 | float radian, /* rotation angle (clockwise, in radian) */ 1490 | float zoom = 1.0f /* zoom factor */ 1491 | ); 1492 | 1493 | HWND EGEAPI getHWnd(); 1494 | HINSTANCE EGEAPI getHInstance(); 1495 | HDC EGEAPI getHDC(PCIMAGE pimg = NULL); 1496 | 1497 | PVOID EGEAPI getProcfunc(); 1498 | long EGEAPI getGraphicsVer(); 1499 | float EGEAPI getfps(); 1500 | 1501 | unsigned int EGEAPI randomize(); 1502 | unsigned int EGEAPI randomize(unsigned int seed); 1503 | 1504 | unsigned int EGEAPI random(unsigned int n = 0); 1505 | double EGEAPI randomf(); 1506 | 1507 | 1508 | int EGEAPI inputbox_getline(const char* title, const char* text, LPSTR buf, int len); 1509 | int EGEAPI inputbox_getline(const wchar_t* title, const wchar_t* text, LPWSTR buf, int len); 1510 | 1511 | 1512 | 1513 | int EGEAPI kbmsg(); 1514 | key_msg EGEAPI getkey(); 1515 | EGE_DEPRECATE(getchEx, "Please use the 'getch' function instead.") 1516 | int EGEAPI getchEx(int flag); 1517 | EGE_DEPRECATE(kbhitEx, "Please use the 'kbhit' function instead.") 1518 | int EGEAPI kbhitEx(int flag); 1519 | int EGEAPI keystate(int key); 1520 | void EGEAPI flushkey(); 1521 | 1522 | #if !defined(_INC_CONIO) && !defined(_CONIO_H_) 1523 | #define _INC_CONIO 1524 | #define _CONIO_H_ 1525 | int EGEAPI getch(); 1526 | int EGEAPI kbhit(); 1527 | #else 1528 | #define getch getchEx 1529 | #define kbhit kbhitEx 1530 | #endif 1531 | 1532 | int EGEAPI mousemsg(); 1533 | mouse_msg EGEAPI getmouse(); 1534 | EGE_DEPRECATE(GetMouseMsg, "Please use the 'getmouse' function instead.") 1535 | MOUSEMSG EGEAPI GetMouseMsg(); 1536 | 1537 | void EGEAPI flushmouse(); 1538 | int EGEAPI showmouse(int bShow); 1539 | int EGEAPI mousepos(int *x, int *y); 1540 | 1541 | /* 1542 | callback function define as: 1543 | int __stdcall on_msg_key(void* param, unsigned msg, int key); 1544 | msg: see 'enum message_event' 1545 | key: keycode 1546 | return zero means process this message, otherwise means pass it and then process with 'getkey' function 1547 | */ 1548 | //int message_addkeyhandler(void* param, LPMSG_KEY_PROC func); 1549 | /* 1550 | callback function define as: 1551 | int __stdcall on_msg_mouse(void* param, unsigned msg, int key, int x, int y); 1552 | msg: see 'enum message_event' 1553 | key: see 'enum message_mouse', if msg==MSG_EVENT_WHELL, key is a int number that indicates the distance the wheel is rotated, expressed in multiples or divisions of WHEEL_DELTA, which is 120. 1554 | x,y: current mouse (x, y) 1555 | return zero means process this message, otherwise means pass it and then process with 'GetMouseMsg' function 1556 | */ 1557 | //int message_addmousehandler(void* param, LPMSG_MOUSE_PROC func); 1558 | int EGEAPI SetCloseHandler(LPCALLBACK_PROC func); 1559 | 1560 | class MUSIC 1561 | { 1562 | public: 1563 | MUSIC(); 1564 | virtual ~MUSIC(); 1565 | 1566 | operator HWND() const { return (HWND)m_dwCallBack; } 1567 | 1568 | public: 1569 | int IsOpen() { return (m_DID != MUSIC_ERROR) ? 1 : 0; } 1570 | 1571 | DWORD OpenFile(const char* filepath); 1572 | DWORD OpenFile(const wchar_t* filepath); 1573 | DWORD Play(DWORD dwFrom = MUSIC_ERROR, DWORD dwTo = MUSIC_ERROR); 1574 | DWORD RepeatPlay(DWORD dwFrom = MUSIC_ERROR, DWORD dwTo = MUSIC_ERROR); 1575 | DWORD Pause(); 1576 | DWORD Seek(DWORD dwTo); 1577 | DWORD SetVolume(float value); 1578 | DWORD Close(); 1579 | DWORD Stop(); 1580 | DWORD GetPosition(); 1581 | DWORD GetLength(); 1582 | 1583 | DWORD GetPlayStatus(); 1584 | 1585 | private: 1586 | DWORD m_DID; 1587 | PVOID m_dwCallBack; 1588 | }; 1589 | 1590 | int EGEAPI ege_compress (void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen); 1591 | int EGEAPI ege_compress2 (void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen, int level); 1592 | int EGEAPI ege_uncompress(void *dest, unsigned long *destLen, const void *source, unsigned long sourceLen); 1593 | unsigned long EGEAPI ege_uncompress_size(const void *source, unsigned long sourceLen); 1594 | 1595 | } 1596 | 1597 | #ifndef EGE_GRAPH_LIB_BUILD 1598 | #if defined(_MSC_VER) && (defined(HIDE_CONSOLE) || !defined(SHOW_CONSOLE)) 1599 | #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 1600 | #endif 1601 | 1602 | #define Sleep(ms) delay_ms(ms) 1603 | #endif 1604 | 1605 | #if !defined(_MSC_VER) 1606 | #define WinMain(...) WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 1607 | #elif defined(_CONSOLE) 1608 | #if (_MSC_VER > 1200) 1609 | #define WinMain(...) main(int argc, char* argv[]) 1610 | #else 1611 | #define WinMain main 1612 | #endif 1613 | #endif 1614 | 1615 | #endif 1616 | --------------------------------------------------------------------------------