├── 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 |
--------------------------------------------------------------------------------