├── core ├── base │ ├── Ptr.cpp │ ├── Resource.h │ ├── Resource.cpp │ ├── Serializable.h │ ├── Buffer.h │ ├── System.h │ ├── Serializer.cpp │ ├── ThreadPool.h │ ├── StringUtil.h │ ├── FileStream.h │ ├── Buffer.cpp │ └── LinkedList.h ├── platform │ ├── Toolkit.cpp │ └── Mouse.h ├── scene │ ├── Component.cpp │ ├── Renderer.cpp │ ├── Component.h │ └── AssetManager.h ├── math │ ├── Ray.inl │ ├── Plane.inl │ ├── Quaternion.inl │ ├── BoundingBox.inl │ ├── BoundingSphere.inl │ ├── LineSegment.h │ ├── MathUtil.cpp │ ├── Matrix.inl │ ├── Math.h │ ├── Vector2.inl │ ├── LineSegment.cpp │ ├── Vector3.inl │ └── Vector4.inl ├── fmake_wasm.props ├── fmake.props ├── 3rd │ ├── base64.h │ └── utf8.h ├── material │ └── Image.inl ├── objects │ ├── Instanced.h │ ├── FontEngine.h │ ├── TextureAtlas.h │ └── Instanced.cpp ├── mgp_core.h └── animation │ ├── AnimationValue.cpp │ ├── AnimationController.h │ └── AnimationValue.h ├── res ├── shaders │ ├── font.vert │ ├── null.frag │ ├── postEffect │ │ ├── fullQuad.vert │ │ ├── passthrough.frag │ │ ├── ssaoMerge.frag │ │ ├── bright.frag │ │ ├── bloomMerge.frag │ │ ├── blurOne.frag │ │ ├── hdrToLdr.frag │ │ ├── blur.frag │ │ ├── gaussianBlur.frag │ │ └── edgeDetect.frag │ ├── min.vert │ ├── min.frag │ ├── deferred │ │ ├── gbuffer.frag │ │ ├── gbuffer.vert │ │ └── colored.frag │ ├── cubemap.vert │ ├── depth.vert │ ├── enviro.vert │ ├── depth.frag │ ├── sprite.frag │ ├── _common.vert │ ├── sprite.vert │ ├── cubemap.frag │ ├── colored.vert │ ├── textured.vert │ ├── textured.frag │ ├── _morph.vert │ ├── font.frag │ ├── _common.frag │ ├── colored.frag │ ├── enviro.frag │ ├── terrain.vert │ ├── _skinning-none.vert │ ├── _lighting_def.glsl │ └── terrain.frag └── ui │ ├── up.png │ ├── band.png │ ├── down.png │ ├── down2.png │ ├── empty.png │ ├── input.png │ ├── left.png │ ├── panel.png │ ├── rect.png │ ├── right.png │ ├── sans.ttf │ ├── track.png │ ├── button.png │ ├── checked.png │ ├── loading.png │ ├── marker.png │ ├── outline.png │ ├── right2.png │ ├── circle12.png │ ├── circle37.png │ ├── circle56.png │ ├── circle80.png │ ├── comboBox.png │ ├── comboBox2.png │ ├── selected.png │ ├── triangle.png │ ├── unchecked.png │ ├── unselected.png │ ├── circle_outline.png │ ├── joystickInner.png │ ├── joystickOuter.png │ ├── circle56_outline.png │ ├── circle80_outline.png │ ├── verticalScrollBar.png │ └── horizontalScrollBar.png ├── doc ├── scene.png ├── animation.png ├── memory.md ├── index.md ├── audio.md ├── physics.md ├── build.md ├── light.md ├── arch.md ├── gltf.md ├── material.md ├── serializer.md ├── start.md └── ui.md ├── screenshot ├── editor.png ├── feaView.png ├── mgpEarth.png ├── particle.png └── terrain.png ├── modules ├── audio │ ├── audio.h │ └── AudioController.h ├── render │ ├── FrameBuffer.cpp │ ├── PostEffect.h │ ├── Shadow.h │ ├── RenderDataManager.h │ └── RenderPath.h ├── waseUI │ └── WaseWindow.h ├── physics │ ├── physics.h │ └── PhysicsGhostObject.h ├── openGL │ ├── CompressedTexture.h │ └── GLRenderer.h ├── fmake_wasm.props ├── ui │ ├── Button.cpp │ ├── ModalLayer.h │ ├── AbsoluteLayout.cpp │ ├── MenuList.h │ ├── ComboBox.h │ ├── Button.h │ ├── Layout.cpp │ ├── ModalLayer.cpp │ ├── AbsoluteLayout.h │ ├── ProgressBar.h │ ├── TreeView.h │ ├── Layout.h │ ├── FormManager.h │ ├── HorizontalLayout.h │ ├── HorizontalLayout.cpp │ ├── Icon.h │ ├── ComboBox.cpp │ ├── FlowLayout.h │ ├── VerticalLayout.cpp │ └── MenuList.cpp ├── fmake.props ├── fmake_full.props ├── script │ └── Script.cpp ├── loader │ └── GltfLoader.h ├── app │ ├── Platform.cpp │ ├── InputListener.h │ ├── AppConfig.h │ ├── CameraCtrl.h │ ├── SceneView.h │ ├── PlatformGlfw.h │ ├── EventTimer.cpp │ └── FirstPersonCamera.h ├── mgp.h └── ai │ ├── AIState.cpp │ ├── AIAgent.cpp │ └── AIController.h ├── example ├── Qt │ ├── main.cpp │ ├── mainwindow.cpp │ ├── mainwindow.h │ ├── .gitignore │ ├── mainwindow.ui │ └── mgpview.h ├── gltf │ ├── main.cpp │ └── fmake.props ├── triangle │ ├── fmake_wasm.props │ └── fmake.props └── ui │ ├── fmake.props │ ├── fmake_wasm.props │ └── main.cpp ├── .gitignore └── README.md /core/base/Ptr.cpp: -------------------------------------------------------------------------------- 1 | //#include "Ptr.h" 2 | -------------------------------------------------------------------------------- /res/shaders/font.vert: -------------------------------------------------------------------------------- 1 | 2 | #include "sprite.vert" -------------------------------------------------------------------------------- /doc/scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/doc/scene.png -------------------------------------------------------------------------------- /res/ui/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/up.png -------------------------------------------------------------------------------- /res/ui/band.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/band.png -------------------------------------------------------------------------------- /res/ui/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/down.png -------------------------------------------------------------------------------- /res/ui/down2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/down2.png -------------------------------------------------------------------------------- /res/ui/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/empty.png -------------------------------------------------------------------------------- /res/ui/input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/input.png -------------------------------------------------------------------------------- /res/ui/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/left.png -------------------------------------------------------------------------------- /res/ui/panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/panel.png -------------------------------------------------------------------------------- /res/ui/rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/rect.png -------------------------------------------------------------------------------- /res/ui/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/right.png -------------------------------------------------------------------------------- /res/ui/sans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/sans.ttf -------------------------------------------------------------------------------- /res/ui/track.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/track.png -------------------------------------------------------------------------------- /doc/animation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/doc/animation.png -------------------------------------------------------------------------------- /res/ui/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/button.png -------------------------------------------------------------------------------- /res/ui/checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/checked.png -------------------------------------------------------------------------------- /res/ui/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/loading.png -------------------------------------------------------------------------------- /res/ui/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/marker.png -------------------------------------------------------------------------------- /res/ui/outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/outline.png -------------------------------------------------------------------------------- /res/ui/right2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/right2.png -------------------------------------------------------------------------------- /res/ui/circle12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle12.png -------------------------------------------------------------------------------- /res/ui/circle37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle37.png -------------------------------------------------------------------------------- /res/ui/circle56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle56.png -------------------------------------------------------------------------------- /res/ui/circle80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle80.png -------------------------------------------------------------------------------- /res/ui/comboBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/comboBox.png -------------------------------------------------------------------------------- /res/ui/comboBox2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/comboBox2.png -------------------------------------------------------------------------------- /res/ui/selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/selected.png -------------------------------------------------------------------------------- /res/ui/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/triangle.png -------------------------------------------------------------------------------- /res/ui/unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/unchecked.png -------------------------------------------------------------------------------- /res/ui/unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/unselected.png -------------------------------------------------------------------------------- /screenshot/editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/screenshot/editor.png -------------------------------------------------------------------------------- /screenshot/feaView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/screenshot/feaView.png -------------------------------------------------------------------------------- /screenshot/mgpEarth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/screenshot/mgpEarth.png -------------------------------------------------------------------------------- /screenshot/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/screenshot/particle.png -------------------------------------------------------------------------------- /screenshot/terrain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/screenshot/terrain.png -------------------------------------------------------------------------------- /res/shaders/null.frag: -------------------------------------------------------------------------------- 1 | void main() 2 | { 3 | // gl_FragDepth = gl_FragCoord.z; 4 | } -------------------------------------------------------------------------------- /res/ui/circle_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle_outline.png -------------------------------------------------------------------------------- /res/ui/joystickInner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/joystickInner.png -------------------------------------------------------------------------------- /res/ui/joystickOuter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/joystickOuter.png -------------------------------------------------------------------------------- /modules/audio/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIO_H_ 2 | #define AUDIO_H_ 3 | 4 | #include "miniaudio.h" 5 | 6 | #endif -------------------------------------------------------------------------------- /res/ui/circle56_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle56_outline.png -------------------------------------------------------------------------------- /res/ui/circle80_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/circle80_outline.png -------------------------------------------------------------------------------- /res/ui/verticalScrollBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/verticalScrollBar.png -------------------------------------------------------------------------------- /res/ui/horizontalScrollBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chunquedong/mgp/HEAD/res/ui/horizontalScrollBar.png -------------------------------------------------------------------------------- /modules/render/FrameBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "FrameBuffer.h" 3 | #include "platform/Toolkit.h" 4 | 5 | namespace mgp 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /core/platform/Toolkit.cpp: -------------------------------------------------------------------------------- 1 | #include "Toolkit.h" 2 | 3 | using namespace mgp; 4 | 5 | 6 | Toolkit* Toolkit::g_instance; 7 | 8 | Toolkit* Toolkit::cur() { return g_instance; } -------------------------------------------------------------------------------- /core/scene/Component.cpp: -------------------------------------------------------------------------------- 1 | #include "Component.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | Component::Component(): _node(NULL) 7 | { 8 | } 9 | Component::~Component() 10 | { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example/Qt/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /res/shaders/postEffect/fullQuad.vert: -------------------------------------------------------------------------------- 1 | // Inputs 2 | in vec2 a_position; 3 | in vec2 a_texCoord; 4 | 5 | // Varying 6 | out vec2 v_texCoord; 7 | 8 | void main() 9 | { 10 | gl_Position = vec4(a_position, 0.0, 1.0); 11 | v_texCoord = a_texCoord; 12 | } -------------------------------------------------------------------------------- /res/shaders/min.vert: -------------------------------------------------------------------------------- 1 | 2 | 3 | uniform mat4 u_worldViewProjectionMatrix; 4 | 5 | in vec3 a_position; 6 | 7 | 8 | 9 | void main() 10 | { 11 | vec4 position = vec4(a_position, 1.0); 12 | gl_Position = u_worldViewProjectionMatrix * position; 13 | } 14 | -------------------------------------------------------------------------------- /example/Qt/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) 5 | : QMainWindow(parent) 6 | , ui(new Ui::MainWindow) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | MainWindow::~MainWindow() 12 | { 13 | delete ui; 14 | } 15 | -------------------------------------------------------------------------------- /res/shaders/min.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | uniform vec4 u_diffuseColor; 10 | 11 | out vec4 FragColor; 12 | 13 | void main() 14 | { 15 | FragColor = u_diffuseColor; 16 | } 17 | -------------------------------------------------------------------------------- /doc/memory.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 内存安全约定 4 | 5 | 1. UPtr表示拥有所有权 6 | 2. SPtr表示共享所有权 7 | 3. 裸指针表示临时对象 8 | 4. 参数传递如果不传递所有权,一般使用裸指针。 9 | 5. 使用uniqueFromInstant从临时对象转为UPtr 10 | 6. UPtr转SPtr: uptr.toShared(); 11 | 7. 共享UPtr: uptr.share(); 12 | 13 | 14 | ## 内存泄漏 15 | 16 | 如果对象public继承自Refable, 那么在程序退出时控制台会打印内存泄漏情况,如果有内存泄漏需要优先处理。 17 | -------------------------------------------------------------------------------- /res/shaders/deferred/gbuffer.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | in vec3 v_normalVector; 10 | 11 | out vec4 FragColor; 12 | 13 | void main() 14 | { 15 | FragColor = vec4(v_normalVector, 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /doc/index.md: -------------------------------------------------------------------------------- 1 | 2 | MGP is a lightweight 3D game engine. 3 | 4 | [Build](build.md) 5 | 6 | [架构](arch.md) 7 | 8 | [开始](start.md) 9 | 10 | [内存安全](memory.md) 11 | 12 | [材质](material.md) 13 | 14 | [UI](ui.md) 15 | 16 | [模型加载](gltf.md) 17 | 18 | [光照](light.md) 19 | 20 | [声音](audio.md) 21 | 22 | [物理引擎](physics.md) 23 | 24 | [序列化](serializer.md) -------------------------------------------------------------------------------- /core/math/Ray.inl: -------------------------------------------------------------------------------- 1 | #include "Ray.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline Ray& Ray::operator*=(const Matrix& matrix) 7 | { 8 | transform(matrix); 9 | return *this; 10 | } 11 | 12 | inline const Ray operator*(const Matrix& matrix, const Ray& ray) 13 | { 14 | Ray r(ray); 15 | r.transform(matrix); 16 | return r; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /core/math/Plane.inl: -------------------------------------------------------------------------------- 1 | #include "Plane.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline Plane& Plane::operator*=(const Matrix& matrix) 7 | { 8 | transform(matrix); 9 | return *this; 10 | } 11 | 12 | inline const Plane operator*(const Matrix& matrix, const Plane& plane) 13 | { 14 | Plane p(plane); 15 | p.transform(matrix); 16 | return p; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /modules/render/PostEffect.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef POST_EFFECT_H_ 3 | #define POST_EFFECT_H_ 4 | 5 | #include "render/RenderStage.h" 6 | 7 | namespace mgp { 8 | 9 | struct Bloom : public RenderStageGroup { 10 | Bloom(RenderPath* _renderPath); 11 | }; 12 | 13 | struct SSAO : public RenderStageGroup { 14 | SSAO(RenderPath* _renderPath); 15 | }; 16 | 17 | } 18 | 19 | #endif //POST_EFFECT_H_ -------------------------------------------------------------------------------- /core/fmake_wasm.props: -------------------------------------------------------------------------------- 1 | name = mgpCore 2 | summary = MGP core 3 | outType = lib 4 | version = 1.0 5 | depends = jsonc 2.0 6 | srcDirs = base/,math/,3rd/,animation/,material/,objects/,platform/,scene/ 7 | incDir = ./ 8 | //debug.defines = GP_USE_MEM_LEAK_DETECTION 9 | defines=GP_NO_LUA_BINDINGS 10 | gcc.extConfigs.cppflags = -std=c++17 11 | emcc.extConfigs.cppflags = -std=c++17 12 | compiler = emcc -------------------------------------------------------------------------------- /modules/waseUI/WaseWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MGPWINDOW_H_ 2 | #define MGPWINDOW_H_ 3 | 4 | #include "platform/Keyboard.h" 5 | #include "platform/Mouse.h" 6 | 7 | namespace waseUI { 8 | void init(); 9 | void finalize(); 10 | bool doFrame(); 11 | 12 | void resize(int w, int h); 13 | bool keyEvent(mgp::Keyboard key); 14 | bool mouseEvent(mgp::Mouse evt); 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /res/shaders/cubemap.vert: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 a_position; 2 | 3 | uniform mat4 u_worldViewProjectionMatrix; 4 | 5 | 6 | out vec3 v_worldPos; 7 | 8 | 9 | void main() 10 | { 11 | v_worldPos = a_position; 12 | vec4 pos = u_worldViewProjectionMatrix * vec4(a_position, 1.0); 13 | 14 | #ifdef SKY_BOX 15 | gl_Position = pos.xyww; 16 | #else 17 | gl_Position = pos; 18 | #endif 19 | } -------------------------------------------------------------------------------- /core/fmake.props: -------------------------------------------------------------------------------- 1 | name = mgpCore 2 | summary = MGP core 3 | outType = lib 4 | version = 1.0 5 | depends = jsonc 2.0, freetype 2.4.12 6 | srcDirs = base/,math/,3rd/,animation/,material/,objects/,platform/,scene/ 7 | incDir = ./ 8 | win32.defines = UNICODE,GP_NO_LUA_BINDINGS,GP_USE_GAMEPAD 9 | //debug.defines = GP_USE_MEM_LEAK_DETECTION 10 | defines=GP_NO_LUA_BINDINGS 11 | gcc.extConfigs.cppflags = -std=c++17 -------------------------------------------------------------------------------- /core/math/Quaternion.inl: -------------------------------------------------------------------------------- 1 | #include "Quaternion.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline const Quaternion Quaternion::operator*(const Quaternion& q) const 7 | { 8 | Quaternion result(*this); 9 | result.multiply(q); 10 | return result; 11 | } 12 | 13 | inline Quaternion& Quaternion::operator*=(const Quaternion& q) 14 | { 15 | multiply(q); 16 | return *this; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /res/shaders/postEffect/passthrough.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | in vec2 v_texCoord; 10 | 11 | out vec4 FragColor; 12 | 13 | uniform sampler2D u_texture; 14 | 15 | void main() 16 | { 17 | FragColor = texture(u_texture, v_texCoord); 18 | } 19 | -------------------------------------------------------------------------------- /core/math/BoundingBox.inl: -------------------------------------------------------------------------------- 1 | #include "BoundingBox.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline BoundingBox& BoundingBox::operator*=(const Matrix& matrix) 7 | { 8 | transform(matrix); 9 | return *this; 10 | } 11 | 12 | inline const BoundingBox operator*(const Matrix& matrix, const BoundingBox& box) 13 | { 14 | BoundingBox b(box); 15 | b.transform(matrix); 16 | return b; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /modules/physics/physics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef GP_USE_MEM_LEAK_DETECTION 4 | #undef new 5 | #endif 6 | 7 | // Bullet Physics 8 | #include 9 | #include 10 | #define BV(v) (btVector3((v).x, (v).y, (v).z)) 11 | #define BQ(q) (btQuaternion((q).x, (q).y, (q).z, (q).w)) 12 | 13 | #ifdef GP_USE_MEM_LEAK_DETECTION 14 | #define new DEBUG_NEW 15 | #endif -------------------------------------------------------------------------------- /core/math/BoundingSphere.inl: -------------------------------------------------------------------------------- 1 | #include "BoundingSphere.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline BoundingSphere& BoundingSphere::operator*=(const Matrix& matrix) 7 | { 8 | transform(matrix); 9 | return *this; 10 | } 11 | 12 | inline const BoundingSphere operator*(const Matrix& matrix, const BoundingSphere& sphere) 13 | { 14 | BoundingSphere s(sphere); 15 | s.transform(matrix); 16 | return s; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /example/Qt/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | QT_BEGIN_NAMESPACE 7 | namespace Ui { 8 | class MainWindow; 9 | } 10 | QT_END_NAMESPACE 11 | 12 | class MainWindow : public QMainWindow 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | MainWindow(QWidget *parent = nullptr); 18 | ~MainWindow(); 19 | 20 | private: 21 | Ui::MainWindow *ui; 22 | }; 23 | #endif // MAINWINDOW_H 24 | -------------------------------------------------------------------------------- /doc/audio.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 声音 4 | 5 | 目前只支持WAV、MP3、OGG格式 6 | 7 | ``` 8 | class MainApp : public Application { 9 | UPtr _audioEngine; 10 | 11 | void initialize() { 12 | 13 | _audioEngine = AudioSource::create("res/audio/engine_loop.ogg", false); 14 | _audioEngine->setLooped(true); 15 | _audioEngine->play(); 16 | } 17 | 18 | void finalize() { 19 | _audioEngine.clear(); 20 | } 21 | }; 22 | ``` 23 | -------------------------------------------------------------------------------- /example/gltf/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "mgp.h" 4 | 5 | using namespace mgp; 6 | 7 | class MainApp : public Application { 8 | void initialize() { 9 | 10 | GltfLoader loader; 11 | auto _scene = loader.load("res/gltf/car.gltf"); 12 | 13 | getView()->setScene(std::move(_scene)); 14 | getView()->initCamera(false); 15 | } 16 | }; 17 | 18 | int main() { 19 | MainApp instance; 20 | return Platform::run(&instance); 21 | } -------------------------------------------------------------------------------- /modules/openGL/CompressedTexture.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPRESSEDTEXTURE_H_ 2 | #define COMPRESSEDTEXTURE_H_ 3 | 4 | #include "material/Texture.h" 5 | 6 | namespace mgp 7 | { 8 | class GLCompressedTexture : public CompressedTexture { 9 | public: 10 | UPtr createCompressedDdsKtx(const char* path); 11 | 12 | UPtr createCompressedPVRTC(const char* path); 13 | 14 | UPtr createCompressedDDS(const char* path); 15 | }; 16 | } 17 | 18 | #endif -------------------------------------------------------------------------------- /res/shaders/depth.vert: -------------------------------------------------------------------------------- 1 | 2 | 3 | /////////////////////////////////////////////////////////// 4 | uniform mat4 u_projectionMatrix; 5 | in vec3 a_position; 6 | 7 | #if defined(SKINNING) 8 | #include "_skinning.vert" 9 | #else 10 | #include "_skinning-none.vert" 11 | #endif 12 | 13 | 14 | #include "_common.vert" 15 | 16 | void main() 17 | { 18 | vec4 position = getPosition(); 19 | gl_Position = u_projectionMatrix * position; 20 | 21 | applyCommonVert(); 22 | } 23 | -------------------------------------------------------------------------------- /modules/fmake_wasm.props: -------------------------------------------------------------------------------- 1 | name = mgpModules 2 | summary = MGP modules 3 | outType = lib 4 | version = 1.0 5 | depends = mgpCore 1.0, jsonc 2.0, draco 1.4.1, bullet 3.24, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = app/,render/,openGL/,loader/,ui/,physics/,waseUI/ 7 | incDir = ./ 8 | //debug.defines = GP_USE_MEM_LEAK_DETECTION 9 | defines=GP_NO_LUA_BINDINGS,GP_GLFW,GLTFIO_DRACO_SUPPORTED,GP_UI,WASE_UI 10 | emcc.extConfigs.cppflags = -std=c++17 11 | compiler = emcc -------------------------------------------------------------------------------- /res/shaders/enviro.vert: -------------------------------------------------------------------------------- 1 | 2 | 3 | uniform mat4 u_worldViewProjectionMatrix; 4 | uniform mat4 u_inverseTransposeWorldMatrix; 5 | uniform mat4 u_worldMatrix; 6 | 7 | in vec3 a_position; 8 | in vec3 a_normal; 9 | 10 | out vec3 v_normalVector; 11 | out vec3 v_position; 12 | 13 | void main(void) { 14 | gl_Position = u_worldViewProjectionMatrix * vec4(a_position, 1.0); 15 | v_position = vec3(u_worldMatrix * vec4(a_position, 1.0)); 16 | v_normalVector = (u_inverseTransposeWorldMatrix * vec4(a_normal, 1.0)).xyz; 17 | } -------------------------------------------------------------------------------- /res/shaders/postEffect/ssaoMerge.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | in vec2 v_texCoord; 6 | 7 | out vec4 FragColor; 8 | 9 | uniform sampler2D u_main; 10 | uniform sampler2D u_ssao; 11 | 12 | void main() 13 | { 14 | vec4 color4 = texture(u_main, v_texCoord); 15 | vec3 color = color4.rgb; 16 | float ao = texture(u_ssao, v_texCoord).r; 17 | 18 | color -= vec3(0.3); 19 | color += vec3(0.3 * ao); 20 | 21 | FragColor = vec4(color, color4.a); 22 | } 23 | -------------------------------------------------------------------------------- /res/shaders/depth.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | in vec2 v_texCoord; 10 | 11 | out vec4 FragColor; 12 | 13 | uniform sampler2D u_texture; 14 | 15 | void main() 16 | { 17 | float depthValue = texture(u_texture, v_texCoord).r; 18 | 19 | #if defined(DEPTH_TO_ALPHA) 20 | FragColor = vec4(1.0, 1.0, 1.0, depthValue); 21 | #else 22 | FragColor = vec4(vec3(depthValue), 1.0); 23 | #endif 24 | } -------------------------------------------------------------------------------- /res/shaders/postEffect/bright.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | in vec2 v_texCoord; 6 | 7 | out vec4 FragColor; 8 | 9 | uniform sampler2D u_texture; 10 | 11 | uniform float u_brightLimit; 12 | 13 | void main() 14 | { 15 | vec3 color = texture(u_texture, v_texCoord).rgb; 16 | float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722)); 17 | if(brightness > u_brightLimit) 18 | FragColor = vec4(color, 1.0); 19 | else 20 | FragColor = vec4(0.0); 21 | } 22 | -------------------------------------------------------------------------------- /example/triangle/fmake_wasm.props: -------------------------------------------------------------------------------- 1 | name = samples-triangle 2 | summary = samples 3 | outType = exe 4 | version = 1.0 5 | depends = mgpCore 1.0, mgpModules 1.0, jsonc 2.0, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = ./ 7 | incDir = ./ 8 | defines=GP_NO_LUA_BINDINGS,GP_GLFW 9 | extConfigs.linkflags=-sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -sSAFE_HEAP=1 --preload-file D:/workspace/code/mgp/res/shaders@res/shaders -gsource-map -sMODULARIZE -s EXPORT_NAME="createMyModule" -s TOTAL_MEMORY=2013265920 -------------------------------------------------------------------------------- /res/shaders/sprite.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | /////////////////////////////////////////////////////////// 10 | // Uniforms 11 | uniform sampler2D u_texture; 12 | 13 | /////////////////////////////////////////////////////////// 14 | // Varyings 15 | in vec2 v_texCoord; 16 | in vec4 v_color; 17 | out vec4 FragColor; 18 | 19 | void main() 20 | { 21 | FragColor = v_color * texture(u_texture, v_texCoord); 22 | } 23 | -------------------------------------------------------------------------------- /res/shaders/postEffect/bloomMerge.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | out vec4 FragColor; 6 | in vec2 v_texCoord; 7 | 8 | uniform sampler2D u_main; 9 | uniform sampler2D u_texture; 10 | const float exposure = 1.0; 11 | 12 | void main() 13 | { 14 | const float gamma = 2.2; 15 | vec3 hdrColor = texture(u_main, v_texCoord).rgb; 16 | vec3 bloomColor = texture(u_texture, v_texCoord).rgb; 17 | hdrColor += bloomColor; // additive blending 18 | 19 | FragColor = vec4(hdrColor, 1.0f); 20 | } -------------------------------------------------------------------------------- /modules/ui/Button.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "Button.h" 3 | //#include "platform/Gamepad.h" 4 | 5 | namespace mgp 6 | { 7 | 8 | Button::Button() : _dataBinding(0) 9 | { 10 | _canFocus = true; 11 | setPadding(4, 12, 4, 12); 12 | _className = "Button"; 13 | } 14 | 15 | Button::~Button() 16 | { 17 | } 18 | 19 | const unsigned int Button::getDataBinding() const 20 | { 21 | return _dataBinding; 22 | } 23 | 24 | void Button::setDataBinding(unsigned int dataBinding) 25 | { 26 | _dataBinding = dataBinding; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /doc/physics.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 物理引擎 4 | 5 | 通过setCollisionObject创建物理对象。 6 | ``` 7 | PhysicsRigidBody::Parameters params; 8 | params.mass = 5; 9 | PhysicsCollisionObject* collisionObject = PhysicsCollisionObject::setCollisionObject(modelNode, PhysicsCollisionObject::RIGID_BODY, 10 | PhysicsCollisionShape::box(), ¶ms); 11 | ``` 12 | 13 | 类型: 14 | - RIGID_BODY 刚体 15 | - CHARACTER 角色 16 | - GHOST_OBJECT 幽灵体 17 | - VEHICLE 载具 18 | - VEHICLE_WHEEL 轮子 19 | 20 | 形状: 21 | - SHAPE_BOX, 22 | - SHAPE_SPHERE, 23 | - SHAPE_CAPSULE, 24 | - SHAPE_MESH, 25 | - SHAPE_HEIGHTFIELD 26 | 27 | -------------------------------------------------------------------------------- /res/shaders/_common.vert: -------------------------------------------------------------------------------- 1 | 2 | #if defined(LIGHTMAP) 3 | in vec2 a_texCoord1; 4 | out vec2 v_texCoord1; 5 | #endif 6 | 7 | #if defined(CLIP_PLANE) 8 | uniform mat4 u_worldMatrix; 9 | uniform vec4 u_clipPlane; 10 | out float v_clipDistance; 11 | #endif 12 | 13 | 14 | void applyCommonVert() { 15 | // Pass the lightmap texture coordinate 16 | #if defined(LIGHTMAP) 17 | v_texCoord1 = a_texCoord1; 18 | #endif 19 | 20 | #if defined(CLIP_PLANE) 21 | v_clipDistance = dot(u_worldMatrix * position, u_clipPlane); 22 | #endif 23 | } 24 | -------------------------------------------------------------------------------- /core/3rd/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_H 2 | #define BASE64_H 3 | 4 | #define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1)) 5 | #define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3)) 6 | 7 | /* 8 | * out is null-terminated encode string. 9 | * return values is out length, exclusive terminating `\0' 10 | */ 11 | unsigned int 12 | base64_encode(const unsigned char *in, unsigned int inlen, char *out); 13 | 14 | /* 15 | * return values is out length 16 | */ 17 | unsigned int 18 | base64_decode(const char *in, unsigned int inlen, unsigned char *out); 19 | 20 | #endif /* BASE64_H */ -------------------------------------------------------------------------------- /core/math/LineSegment.h: -------------------------------------------------------------------------------- 1 | #ifndef LINESEGMENT_H_ 2 | #define LINESEGMENT_H_ 3 | 4 | #include "Vector3.h" 5 | 6 | namespace mgp 7 | { 8 | class LineSegment { 9 | public: 10 | Vector3 p1; 11 | Vector3 p2; 12 | 13 | LineSegment(const Vector3& f, const Vector3& t) : p1(f), p2(t) {} 14 | 15 | bool intersection(const LineSegment& that, Vector3* intersectPoint, bool strict = true) const; 16 | Float distanceToPoint(const Vector3& point) const; 17 | }; 18 | 19 | bool triangleNormal(const Vector3& p1, const Vector3& p2, const Vector3& p3, Vector3* normal); 20 | 21 | } 22 | 23 | #endif //MATH_BASE_H_ -------------------------------------------------------------------------------- /res/shaders/postEffect/blurOne.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | in vec2 v_texCoord; 6 | out float fragColor; 7 | 8 | uniform sampler2D u_texture; 9 | 10 | void main() { 11 | vec2 texelSize = 1.0 / vec2(textureSize(u_texture, 0)); 12 | float result = 0.0; 13 | for (int x = -2; x < 2; ++x) 14 | { 15 | for (int y = -2; y < 2; ++y) 16 | { 17 | vec2 offset = vec2(float(x), float(y)) * texelSize; 18 | result += texture(u_texture, v_texCoord + offset).r; 19 | } 20 | } 21 | fragColor = result / (4.0 * 4.0); 22 | } -------------------------------------------------------------------------------- /res/shaders/sprite.vert: -------------------------------------------------------------------------------- 1 | 2 | 3 | /////////////////////////////////////////////////////////// 4 | // Uniforms 5 | uniform mat4 u_projectionMatrix; 6 | 7 | /////////////////////////////////////////////////////////// 8 | // Attributes 9 | in vec3 a_position; 10 | in vec2 a_texCoord; 11 | in vec4 a_color; 12 | 13 | 14 | /////////////////////////////////////////////////////////// 15 | // Varyings 16 | out vec2 v_texCoord; 17 | out vec4 v_color; 18 | 19 | 20 | void main() 21 | { 22 | gl_Position = u_projectionMatrix * vec4(a_position, 1.0); 23 | v_texCoord = a_texCoord; 24 | v_color = a_color; 25 | } 26 | -------------------------------------------------------------------------------- /example/ui/fmake.props: -------------------------------------------------------------------------------- 1 | name = samples-ui 2 | summary = samples 3 | outType = exe 4 | version = 1.0 5 | depends = mgpCore 1.0, mgpModules 1.0, glfw 3.3.8, glew 2.2.0, miniaudio 0.11, bullet 3.24, freetype 2.4.12, jsonc 2.0, ljs 1.0, curl 8, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = ./ 7 | incDir = ./ 8 | win32.defines = UNICODE 9 | win32.extLibs = OpenGL32.lib,GLU32.lib,XInput.lib,Winmm.lib,kernel32.lib,user32.lib,gdi32.lib,winspool.lib,comdlg32.lib,advapi32.lib,shell32.lib,ole32.lib,oleaut32.lib,uuid.lib,odbc32.lib,odbccp32.lib,ws2_32.lib,winmm.lib,wldap32.lib 10 | win32.extConfigs.linkflags = /SUBSYSTEM:CONSOLE -------------------------------------------------------------------------------- /core/material/Image.inl: -------------------------------------------------------------------------------- 1 | #include "Image.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline unsigned char* Image::getData() const 7 | { 8 | return _data; 9 | } 10 | 11 | inline void Image::setData(unsigned char* data) { 12 | if (_data == data) return; 13 | 14 | if (_data) { 15 | free(_data); 16 | } 17 | _data = data; 18 | } 19 | 20 | inline Image::Format Image::getFormat() const 21 | { 22 | return _format; 23 | } 24 | 25 | inline unsigned int Image::getHeight() const 26 | { 27 | return _height; 28 | } 29 | 30 | inline unsigned int Image::getWidth() const 31 | { 32 | return _width; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/fmake.props: -------------------------------------------------------------------------------- 1 | name = mgpModules 2 | summary = MGP modules 3 | outType = lib 4 | version = 1.0 5 | depends = mgpCore 1.0, glfw 3.3.8, glew 2.2.0, bullet 3.24, freetype 2.4.12, jsonc 2.0, ljs 1.0, curl 8, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0, miniaudio 0.11 6 | srcDirs = ai/,app/,audio/,physics/,render/,script/,waseUI/,openGL/,loader/ 7 | incDir = ./ 8 | win32.defines = UNICODE,GP_NO_LUA_BINDINGS,GP_GLFW,CURL_DISABLE_LDAP,CURL_STATICLIB 9 | //debug.defines = GP_USE_MEM_LEAK_DETECTION 10 | defines=GP_NO_LUA_BINDINGS,GP_GLFW,CURL_DISABLE_LDAP,CURL_STATICLIB,NVGSWU_GL3,WASE_UI 11 | gcc.extConfigs.cppflags = -std=c++14 12 | -------------------------------------------------------------------------------- /example/gltf/fmake.props: -------------------------------------------------------------------------------- 1 | name = samples-gltf 2 | summary = samples 3 | outType = exe 4 | version = 1.0 5 | depends = mgpCore 1.0, mgpModules 1.0, glfw 3.3.8, glew 2.2.0, miniaudio 0.11, bullet 3.24, freetype 2.4.12, jsonc 2.0, ljs 1.0, curl 8, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = ./ 7 | incDir = ./ 8 | win32.defines = UNICODE,GP_NO_LUA_BINDINGS,GP_GLFW 9 | win32.extLibs = OpenGL32.lib,GLU32.lib,XInput.lib,Winmm.lib,kernel32.lib,user32.lib,gdi32.lib,winspool.lib,comdlg32.lib,advapi32.lib,shell32.lib,ole32.lib,oleaut32.lib,uuid.lib,odbc32.lib,odbccp32.lib,ws2_32.lib,winmm.lib,wldap32.lib 10 | win32.extConfigs.linkflags = /SUBSYSTEM:CONSOLE -------------------------------------------------------------------------------- /example/triangle/fmake.props: -------------------------------------------------------------------------------- 1 | name = samples-triangle 2 | summary = samples 3 | outType = exe 4 | version = 1.0 5 | depends = mgpModules 1.0, mgpCore 1.0, glfw 3.3.8, glew 2.2.0, miniaudio 0.11, bullet 3.24, freetype 2.4.12, jsonc 2.0, ljs 1.0, curl 8, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = ./ 7 | incDir = ./ 8 | win32.defines = UNICODE,GP_NO_LUA_BINDINGS,GP_GLFW 9 | win32.extLibs = OpenGL32.lib,GLU32.lib,XInput.lib,Winmm.lib,kernel32.lib,user32.lib,gdi32.lib,winspool.lib,comdlg32.lib,advapi32.lib,shell32.lib,ole32.lib,oleaut32.lib,uuid.lib,odbc32.lib,odbccp32.lib,ws2_32.lib,winmm.lib,wldap32.lib 10 | win32.extConfigs.linkflags = /SUBSYSTEM:CONSOLE -------------------------------------------------------------------------------- /core/scene/Renderer.cpp: -------------------------------------------------------------------------------- 1 | #include "Renderer.h" 2 | //#include "GLRenderer.h" 3 | #include "platform/Toolkit.h" 4 | 5 | using namespace mgp; 6 | 7 | Renderer* g_rendererInstance; 8 | 9 | Renderer* Renderer::cur() { 10 | /*if (g_rendererInstance == NULL) { 11 | g_rendererInstance = new GLRenderer(); 12 | }*/ 13 | return g_rendererInstance; 14 | } 15 | 16 | unsigned int Renderer::getDpWidth() { return (unsigned int)(getWidth() / Toolkit::cur()->getScreenScale()); } 17 | unsigned int Renderer::getDpHeight() { return (unsigned int)(getHeight() / Toolkit::cur()->getScreenScale()); } 18 | 19 | void Renderer::finalize() { 20 | delete g_rendererInstance; 21 | g_rendererInstance = NULL; 22 | } 23 | -------------------------------------------------------------------------------- /core/math/MathUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "MathUtil.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | void MathUtil::smooth(Float* x, Float target, Float elapsedTime, Float responseTime) 8 | { 9 | GP_ASSERT(x); 10 | 11 | if (elapsedTime > 0) 12 | { 13 | *x += (target - *x) * elapsedTime / (elapsedTime + responseTime); 14 | } 15 | } 16 | 17 | void MathUtil::smooth(Float* x, Float target, Float elapsedTime, Float riseTime, Float fallTime) 18 | { 19 | GP_ASSERT(x); 20 | 21 | if (elapsedTime > 0) 22 | { 23 | Float delta = target - *x; 24 | *x += delta * elapsedTime / (elapsedTime + (delta > 0 ? riseTime : fallTime)); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /modules/fmake_full.props: -------------------------------------------------------------------------------- 1 | name = mgpModules 2 | summary = MGP modules 3 | outType = lib 4 | version = 1.0 5 | depends = mgpCore 1.0, glfw 3.3.8, glew 2.2.0, bullet 3.24, freetype 2.4.12, jsonc 2.0, ljs 1.0, curl 8, draco 1.4.1, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0, miniaudio 0.11 6 | srcDirs = ai/,app/,audio/,physics/,render/,script/,waseUI/,openGL/,loader/,ui/ 7 | incDir = ./ 8 | win32.defines = UNICODE,GP_NO_LUA_BINDINGS,GP_GLFW,CURL_DISABLE_LDAP,CURL_STATICLIB 9 | //debug.defines = GP_USE_MEM_LEAK_DETECTION 10 | defines=GP_NO_LUA_BINDINGS,GP_GLFW,CURL_DISABLE_LDAP,CURL_STATICLIB,GLTFIO_DRACO_SUPPORTED,GP_DDSKTX,GP_PVR,GP_DDS,NVGSWU_GL3,WASE_UI,GP_UI 11 | gcc.extConfigs.cppflags = -std=c++14 -------------------------------------------------------------------------------- /res/shaders/postEffect/hdrToLdr.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | in vec2 v_texCoord; 10 | 11 | out vec4 FragColor; 12 | 13 | uniform sampler2D u_texture; 14 | 15 | #include "../_common.frag" 16 | 17 | void main() 18 | { 19 | FragColor = texture(u_texture, v_texCoord); 20 | 21 | vec3 color = FragColor.rgb; 22 | 23 | #ifdef TONE_MAPPING 24 | color = hdrTonemapping(color); 25 | #else 26 | color = hdrTonemapping2(color); 27 | #endif 28 | 29 | #ifdef GAMMA 30 | color = gammaCorrect(color); 31 | #endif 32 | 33 | FragColor.rgb = color; 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | engine/Debug/ 3 | external-deps/ 4 | x64/ 5 | build/ 6 | build-* 7 | shader.err 8 | res/terrain/tmp 9 | fastEarthCache/ 10 | cache/ 11 | doxygenOut/ 12 | res/particles/ 13 | res/skybox/ 14 | res/terrain/ 15 | res/shaders/billboard.frag 16 | res/shaders/billboard.vert 17 | res/shaders/line.frag 18 | res/shaders/line.vert 19 | res/shaders/water.frag 20 | res/image/ 21 | res/gltf/ 22 | res/materials/ 23 | res/fastEarth/ 24 | res/shaders/custom/ 25 | res/cae/ 26 | res/shaders/IBL/ 27 | res/ui/comboBox.png~ 28 | *autosave.kra 29 | *.png~ 30 | res/audio/engine_loop.ogg 31 | res/icon/ 32 | res/game/ 33 | test.scene 34 | res/assets/ 35 | test2.scene 36 | *.scene 37 | *.log 38 | ui.hml 39 | res/imp/ 40 | res/boxing/ 41 | -------------------------------------------------------------------------------- /modules/ui/ModalLayer.h: -------------------------------------------------------------------------------- 1 | #ifndef MODAL_LAYER_H_ 2 | #define MODAL_LAYER_H_ 3 | 4 | #include "ScrollContainer.h" 5 | #include "Label.h" 6 | #include "Theme.h" 7 | #include "base/Properties.h" 8 | #include 9 | 10 | namespace mgp 11 | { 12 | 13 | class ModalLayer : public Container { 14 | friend class Control; 15 | 16 | int _modal = 1; 17 | public: 18 | 19 | protected: 20 | ModalLayer(); 21 | ~ModalLayer(); 22 | 23 | void controlEvent(Listener::EventType evt); 24 | public: 25 | unsigned int draw(Form* form, const Rectangle& clip, RenderInfo* view); 26 | 27 | void add(Control* content, int modal); 28 | void pop(); 29 | void remove(Control* content); 30 | }; 31 | 32 | } 33 | 34 | 35 | #endif -------------------------------------------------------------------------------- /core/scene/Component.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPONENT_H 2 | #define COMPONENT_H 3 | 4 | #include "base/Serializable.h" 5 | 6 | namespace mgp 7 | { 8 | class Node; 9 | 10 | class Component 11 | { 12 | friend void doFree(Component* p); 13 | protected: 14 | Node* _node; 15 | public: 16 | Component(); 17 | protected: 18 | virtual ~Component(); 19 | 20 | public: 21 | /** 22 | * Sets the node associated with this camera. 23 | */ 24 | virtual void setNode(Node* node) { _node = node; } 25 | }; 26 | 27 | //For UniquePtr<> 28 | inline void doFree(Component* p) { 29 | Refable* r = dynamic_cast(p); 30 | if (r) { 31 | r->release(); 32 | } 33 | else { 34 | delete p; 35 | } 36 | } 37 | 38 | } 39 | #endif // COMPONENT_H 40 | -------------------------------------------------------------------------------- /core/base/Resource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | #ifndef RESOURCE_H 11 | #define RESOURCE_H 12 | 13 | 14 | #include "Ref.h" 15 | #include "Stream.h" 16 | 17 | namespace mgp 18 | { 19 | 20 | class Resource : public Refable { 21 | protected: 22 | std::string _id; 23 | public: 24 | static std::string genId(); 25 | 26 | Resource(); 27 | Resource(const std::string& id); 28 | 29 | void setId(const std::string& id) { _id = id; } 30 | const std::string& getId() { return _id; } 31 | 32 | virtual void write(Stream* file) = 0; 33 | virtual bool read(Stream* file) = 0; 34 | }; 35 | 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /core/base/Resource.cpp: -------------------------------------------------------------------------------- 1 | #include "Resource.h" 2 | #include "System.h" 3 | #include 4 | 5 | using namespace mgp; 6 | 7 | std::string Resource::genId() { 8 | static int baseId = 0; 9 | if (baseId == 0) { 10 | srand(time(0)); 11 | baseId = rand(); 12 | } 13 | static int64_t lastTime = 0; 14 | static int seq = 0; 15 | 16 | int64_t id = System::currentTimeMillis(); 17 | if (id == lastTime) { 18 | ++seq; 19 | } 20 | else { 21 | lastTime = id; 22 | seq = 0; 23 | } 24 | 25 | char buffer[128]; 26 | snprintf(buffer, 128, "%d_%lld_%d", baseId, id, seq); 27 | return buffer; 28 | } 29 | 30 | Resource::Resource() : _id(genId()) { 31 | } 32 | 33 | Resource::Resource(const std::string& id) : _id(id) { 34 | if (_id.size() == 0) { 35 | _id = genId(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## MGP 3 | 4 | MGP is a lightweight 3D game engine. 5 | 6 | 7 | #### Features 8 | 9 | - Cross-platform: Windows, macOS, Linux, WebAssembly 10 | - Rendering: OpenGL ES rendering backends with PBR, CSM 11 | - PostEffect: SSAO, bloom, FXAA 12 | - Assets: Importing GLTF 13 | - UI: Build-in Declarative UI system 14 | - Text: Dynamic load TTF fonts with unicode supporting 15 | - Animation: Animation system with skeletal character animation 16 | - Terrain: Height map based terrains with LOD 17 | - Physics: Powered by Bullet 18 | - Audio: 3D audio system with mp3 OGG support 19 | 20 | ## Doc 21 | [Learn More](doc/index.md) 22 | 23 | 24 | ## Screenshot 25 | ### Editor 26 | ![image](screenshot/editor.png) 27 | 28 | ### 3D Geospatial Visualizing 29 | ![image](screenshot/mgpEarth.png) 30 | 31 | ### Finite Element Simulation 32 | ![image](screenshot/feaView.png) 33 | -------------------------------------------------------------------------------- /modules/ui/AbsoluteLayout.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "Control.h" 3 | #include "AbsoluteLayout.h" 4 | #include "Container.h" 5 | 6 | namespace mgp 7 | { 8 | 9 | static AbsoluteLayout* __instance; 10 | 11 | AbsoluteLayout::AbsoluteLayout() 12 | { 13 | } 14 | 15 | AbsoluteLayout::~AbsoluteLayout() 16 | { 17 | __instance = NULL; 18 | } 19 | 20 | UPtr AbsoluteLayout::create() 21 | { 22 | if (!__instance) 23 | { 24 | __instance = new AbsoluteLayout(); 25 | } 26 | else 27 | { 28 | __instance->addRef(); 29 | } 30 | 31 | return UPtr(__instance); 32 | } 33 | 34 | Layout::Type AbsoluteLayout::getType() 35 | { 36 | return Layout::LAYOUT_ABSOLUTE; 37 | } 38 | 39 | void AbsoluteLayout::update(const Container* container) 40 | { 41 | // Nothing to do for absolute layout 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /core/objects/Instanced.h: -------------------------------------------------------------------------------- 1 | #ifndef INSTANCED_H_ 2 | #define INSTANCED_H_ 3 | #include "scene/Model.h" 4 | 5 | namespace mgp 6 | { 7 | 8 | /** 9 | * Instancing is a technique where we draw many (equal mesh data) objects at once with a single render call. 10 | */ 11 | class Instanced : public Drawable { 12 | std::vector _instanceMatrix; 13 | int _instanceCount; 14 | BufferHandle _instanceVbo; 15 | UPtr _model; 16 | public: 17 | Instanced(); 18 | ~Instanced(); 19 | 20 | void setModel(UPtr model); 21 | Drawable* getModel() { return _model.get(); } 22 | 23 | void setInstanceMatrix(Matrix* data, int count); 24 | void clear(); 25 | void add(const Matrix& matrix); 26 | void finish(); 27 | void setDrawCall(DrawCall* drawCall); 28 | unsigned int draw(RenderInfo *view) override; 29 | }; 30 | 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /res/shaders/deferred/gbuffer.vert: -------------------------------------------------------------------------------- 1 | 2 | uniform mat4 u_projectionMatrix; 3 | uniform mat4 u_inverseTransposeWorldViewMatrix; 4 | 5 | in vec3 a_position; 6 | 7 | #define LIGHTING 8 | 9 | #if defined(SKINNING) 10 | #include "../_skinning.vert" 11 | #else 12 | #include "../_skinning-none.vert" 13 | #endif 14 | 15 | out vec3 v_normalVector; 16 | 17 | void main() 18 | { 19 | vec4 position = getPosition(); 20 | gl_Position = u_projectionMatrix * position; 21 | 22 | vec3 normal = getNormal(); 23 | // Transform the normal, tangent and binormals to view space. 24 | mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz); 25 | vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal); 26 | 27 | v_normalVector = normalVector; 28 | } 29 | -------------------------------------------------------------------------------- /modules/script/Script.cpp: -------------------------------------------------------------------------------- 1 | #include "Script.h" 2 | #include "ScriptController.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | Script::Script() : _scope(GLOBAL), _env(0) 8 | { 9 | } 10 | 11 | Script::~Script() 12 | { 13 | ScriptController::cur()->unloadScript(this); 14 | } 15 | 16 | const char* Script::getPath() const 17 | { 18 | return _path.c_str(); 19 | } 20 | 21 | Script::Scope Script::getScope() const 22 | { 23 | return _scope; 24 | } 25 | 26 | bool Script::functionExists(const char* name) const 27 | { 28 | return ScriptController::cur()->functionExists(name, this); 29 | } 30 | 31 | bool Script::reload() 32 | { 33 | ScriptController* sc = ScriptController::cur(); 34 | 35 | // First unload our current script 36 | sc->unloadScript(this); 37 | 38 | // Now attempt to reload the script 39 | return ScriptController::cur()->loadScript(this); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /doc/build.md: -------------------------------------------------------------------------------- 1 | 2 | ### Build 3 | 4 | #### Build Dependencies 5 | 1. install JVM and [Fanx](https://github.com/fanx-dev/fanx/releases) 6 | 7 | 2. build and install [fmake](https://github.com/) 8 | 9 | 3. build [third-party dependencies](https://gitee.com/chunquedong/third-party): 10 | ``` 11 | sh build.sh -debug 12 | ``` 13 | 4. build [jsonc](https://github.com/chunquedong/jsonc): 14 | ``` 15 | fan fmake libjsonc.props -debug 16 | ``` 17 | 1. build sric and wase 18 | 19 | build [Wase](https://github.com/sric-language/wase) or remove WASE_UI in modules/fmake.props 20 | 21 | #### Build MGP 22 | 1. build 23 | ``` 24 | fan fmake core/fmake.props -debug 25 | fan fmake modules/fmake.props -debug 26 | ``` 27 | 2. generate IDE project file 28 | ``` 29 | sh build.sh -G -debug 30 | ``` 31 | 32 | ### WebAssembly 33 | 34 | ``` 35 | fan fmake core/fmake_wasm.props 36 | fan fmake modules/fmake_wasm.props 37 | ``` 38 | -------------------------------------------------------------------------------- /doc/light.md: -------------------------------------------------------------------------------- 1 | 2 | ## 灯光 3 | 4 | 支持方向光、点光源、聚光灯。目前只有方向光支持产生阴影。 5 | 灯光颜色值可以大于1.0 6 | 7 | ``` 8 | Node* addLight(Scene* _scene, Vector3 eyePosition, Vector3 lookTarget) { 9 | //创建灯光 10 | UPtr directionalLight = Light::createDirectional(Vector3(10.0, 10.0, 10.0)); 11 | 12 | //创建结点 13 | UPtr _directionalLightNode = Node::create("directionalLight"); 14 | _directionalLightNode->setLight(std::move(directionalLight)); 15 | 16 | //设置位置和方向 17 | Matrix m; 18 | Matrix::createLookAt(eyePosition, lookTarget, Vector3::unitY(), &m, false); 19 | _directionalLightNode->setMatrix(m); 20 | 21 | //添加到场景 22 | Node* node = _directionalLightNode.get(); 23 | _scene->addNode(std::move(_directionalLightNode)); 24 | return node; 25 | } 26 | ``` 27 | 28 | ## 灯光作用范围 29 | 30 | 物体和灯光多有setLightMask方法,只有在同一组的灯光才照亮物体。 31 | -------------------------------------------------------------------------------- /example/ui/fmake_wasm.props: -------------------------------------------------------------------------------- 1 | name = samples-ui 2 | summary = samples 3 | outType = exe 4 | version = 1.0 5 | depends = mgpCore 1.0, mgpModules 1.0, jsonc 2.0, sric 1.0, waseGraphics 1.0, waseGui 1.0, serial 1.0, waseNanovg 1.0 6 | srcDirs = ./ 7 | incDir = ./ 8 | defines=GP_NO_LUA_BINDINGS,GP_GLFW 9 | extConfigs.linkflags=-sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 -sFULL_ES2 -sFULL_ES3 \ 10 | --preload-file C:/workspace/code/mgp/res/shaders@res/shaders --preload-file C:/workspace/code/mgp/res/ui@res/ui --preload-file C:/workspace/code/mgp/res/image@res/image -gsource-map \ 11 | -sMODULARIZE -s EXPORT_NAME="createMyModule" -s TOTAL_MEMORY=2013265920 -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=$stringToUTF8OnStack -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,UTF8ToString \ 12 | --js-library C:/workspace/code/mgpPro/wasm/library.js --extern-pre-js C:/workspace/code/mgpPro/wasm/util.js \ 13 | -sEXPORTED_FUNCTIONS=_main,_malloc,_free -------------------------------------------------------------------------------- /res/shaders/cubemap.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | #ifdef EQUIRECTANGULAR_MAP 10 | uniform sampler2D u_diffuseTexture; 11 | #else 12 | uniform samplerCube u_diffuseTexture; 13 | #endif 14 | 15 | in vec3 v_worldPos; 16 | out vec4 FragColor; 17 | 18 | const vec2 invAtan = vec2(0.1591, 0.3183); 19 | vec2 SampleSphericalMap(vec3 v) 20 | { 21 | vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); 22 | uv *= invAtan; 23 | uv += 0.5; 24 | return uv; 25 | } 26 | 27 | void main() 28 | { 29 | #ifdef EQUIRECTANGULAR_MAP 30 | vec2 uv = SampleSphericalMap(normalize(v_worldPos)); // make sure to normalize localPos 31 | FragColor = texture(u_diffuseTexture, uv); 32 | #else 33 | FragColor = texture(u_diffuseTexture, v_worldPos); 34 | #endif 35 | 36 | //FragColor = vec4(v_texCoord, 1.0); 37 | } -------------------------------------------------------------------------------- /modules/ui/MenuList.h: -------------------------------------------------------------------------------- 1 | #ifndef MENU_LIST_H_ 2 | #define MENU_LIST_H_ 3 | 4 | #include "ScrollContainer.h" 5 | #include "Label.h" 6 | #include "Theme.h" 7 | #include "base/Properties.h" 8 | #include 9 | 10 | namespace mgp 11 | { 12 | 13 | class MenuList : public ScrollContainer, public Control::Listener { 14 | friend class Control; 15 | std::vector _items; 16 | int _selectIndex = -1; 17 | public: 18 | 19 | protected: 20 | MenuList(); 21 | ~MenuList(); 22 | 23 | virtual void onSerialize(Serializer* serializer) override; 24 | 25 | virtual void onDeserialize(Serializer* serializer) override; 26 | 27 | void controlEvent(Control* control, EventType evt) override; 28 | 29 | void measureSize() override; 30 | public: 31 | int getSelectIndex() { return _selectIndex; } 32 | void initItems(std::vector& items); 33 | 34 | void show(Control* any); 35 | void close(); 36 | }; 37 | 38 | } 39 | 40 | 41 | #endif -------------------------------------------------------------------------------- /res/shaders/colored.vert: -------------------------------------------------------------------------------- 1 | #include "_lighting_def.glsl" 2 | 3 | 4 | 5 | #if defined(VERTEX_COLOR) 6 | in vec3 a_color; 7 | out vec3 v_color; 8 | #elif defined(VERTEX_COLOR4) 9 | in vec4 a_color; 10 | out vec4 v_color; 11 | #endif 12 | 13 | /////////////////////////////////////////////////////////// 14 | uniform mat4 u_projectionMatrix; 15 | in vec3 a_position; 16 | 17 | #if defined(SKINNING) 18 | #include "_skinning.vert" 19 | #else 20 | #include "_skinning-none.vert" 21 | #endif 22 | 23 | #if defined(LIGHTING) 24 | #include "_lighting.vert" 25 | #endif 26 | 27 | #include "_common.vert" 28 | 29 | void main() 30 | { 31 | vec4 position = getPosition(); 32 | gl_Position = u_projectionMatrix * position; 33 | 34 | #if defined (LIGHTING) 35 | applyLight(position); 36 | #endif 37 | 38 | // Pass the vertex color 39 | #if defined(VERTEX_COLOR) || defined(VERTEX_COLOR4) 40 | v_color = a_color; 41 | #endif 42 | 43 | applyCommonVert(); 44 | } 45 | -------------------------------------------------------------------------------- /modules/loader/GltfLoader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef GLTFLOADER_H_ 9 | #define GLTFLOADER_H_ 10 | 11 | #include "base/Base.h" 12 | #include "scene/Mesh.h" 13 | #include "scene/Scene.h" 14 | #include "scene/Node.h" 15 | 16 | namespace mgp 17 | { 18 | /** 19 | * Loading GLTF format from file or buffer. 20 | * support skin animation and morph animation 21 | */ 22 | class GltfLoader { 23 | public: 24 | enum LightingType { 25 | Pbr = 1, //physic base lighting 26 | NoSpecular = 2, //no specular lighting 27 | Ldr = 4, //convert result from HDR to LDR 28 | }; 29 | 30 | //LightingType: Pbr | NoSpecular | Ldr 31 | int lighting = 0; 32 | 33 | UPtr load(const std::string &file); 34 | UPtr loadFromBuf(const char* file_data, size_t file_size); 35 | std::vector > loadSkins(const std::string& file); 36 | }; 37 | } 38 | 39 | #endif //GLTFLOADER_H_ -------------------------------------------------------------------------------- /example/Qt/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | CMakeLists.txt.user* 41 | 42 | # xemacs temporary files 43 | *.flc 44 | 45 | # Vim temporary files 46 | .*.swp 47 | 48 | # Visual Studio generated files 49 | *.ib_pdb_index 50 | *.idb 51 | *.ilk 52 | *.pdb 53 | *.sln 54 | *.suo 55 | *.vcproj 56 | *vcproj.*.*.user 57 | *.ncb 58 | *.sdf 59 | *.opensdf 60 | *.vcxproj 61 | *vcxproj.* 62 | 63 | # MinGW generated files 64 | *.Debug 65 | *.Release 66 | 67 | # Python byte code 68 | *.pyc 69 | 70 | # Binaries 71 | # -------- 72 | *.dll 73 | *.exe 74 | 75 | -------------------------------------------------------------------------------- /modules/ui/ComboBox.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMBO_BOX_H_ 2 | #define _COMBO_BOX_H_ 3 | 4 | #include "Container.h" 5 | #include "Button.h" 6 | #include "Theme.h" 7 | #include "base/Properties.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace mgp 13 | { 14 | 15 | class ComboBox : public Button, public Control::Listener { 16 | friend class Control; 17 | 18 | std::vector _items; 19 | 20 | int _selectIndex = -1; 21 | 22 | ThemeImage* _image = NULL; 23 | 24 | public: 25 | 26 | std::vector& getItems() { return _items; } 27 | 28 | int getSelectIndex() { return _selectIndex; } 29 | void setSelectIndex(int v, bool fireEvent = true); 30 | 31 | protected: 32 | ComboBox(); 33 | ~ComboBox(); 34 | 35 | virtual void onSerialize(Serializer* serializer); 36 | 37 | virtual void onDeserialize(Serializer* serializer); 38 | 39 | void controlEvent(Control::Listener::EventType evt); 40 | 41 | void controlEvent(Control* control, EventType evt); 42 | private: 43 | ComboBox(const ComboBox& copy) = delete; 44 | }; 45 | 46 | 47 | } 48 | 49 | 50 | #endif -------------------------------------------------------------------------------- /res/shaders/postEffect/blur.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | // Uniforms 6 | uniform sampler2D u_texture; 7 | 8 | 9 | // Inputs 10 | in vec2 v_texCoord; 11 | out vec4 FragColor; 12 | 13 | void main() 14 | { 15 | vec2 offset = 1.0 / vec2(textureSize(u_texture, 0)); 16 | vec2 offsets[9] = vec2[]( 17 | vec2(-offset.x, offset.y), // 左上 18 | vec2( 0.0f, offset.y), // 正上 19 | vec2( offset.x, offset.y), // 右上 20 | vec2(-offset.x, 0.0f), // 左 21 | vec2( 0.0f, 0.0f), // 中 22 | vec2( offset.x, 0.0f), // 右 23 | vec2(-offset.x, -offset.y), // 左下 24 | vec2( 0.0f, -offset.y), // 正下 25 | vec2( offset.x, -offset.y) // 右下 26 | ); 27 | 28 | float kernel[9] = float[]( 29 | 1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0, 30 | 2.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 31 | 1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0 32 | ); 33 | 34 | vec3 col = vec3(0.0); 35 | for(int i = 0; i < 9; i++) 36 | { 37 | vec3 sampleTex = vec3(texture(u_texture, v_texCoord.st + offsets[i])); 38 | col += sampleTex * kernel[i]; 39 | } 40 | FragColor = vec4(col, 1.0); 41 | } -------------------------------------------------------------------------------- /example/ui/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "mgp.h" 4 | #include "waseGui.h" 5 | 6 | using namespace sric; 7 | using namespace waseGui; 8 | using namespace mgp; 9 | 10 | class MainApp : public Application { 11 | 12 | void initialize() { 13 | auto frame = new_(); 14 | { 15 | auto it = new_(); 16 | it->setText("Button"); 17 | it->onClick = ([=](RefPtr w) { 18 | waseGui::Toast::showText("hello world"); 19 | }); 20 | frame->add(std::move(it)); 21 | frame->background.rgba = 0; 22 | } 23 | frame->show(); 24 | } 25 | 26 | void render(float elapsedTime) override { 27 | Renderer::cur()->clear(Renderer::CLEAR_COLOR_DEPTH_STENCIL, Vector4::fromColor(0x888888ff)); 28 | Application::render(elapsedTime); 29 | } 30 | 31 | }; 32 | 33 | int main() { 34 | printf("main start\n"); 35 | 36 | #if __EMSCRIPTEN__ 37 | MainApp* instance = new MainApp(); 38 | return Platform::run(instance); 39 | #else 40 | MainApp instance; 41 | return Platform::run(&instance); 42 | #endif 43 | } -------------------------------------------------------------------------------- /modules/app/Platform.cpp: -------------------------------------------------------------------------------- 1 | // Implementation of base platform-agnostic platform functionality. 2 | #include "base/Base.h" 3 | #include "Platform.h" 4 | #include "app/Application.h" 5 | //#include "script/ScriptController.h" 6 | #include "PlatformGlfw.h" 7 | 8 | namespace mgp 9 | { 10 | 11 | Platform* Platform::_cur = NULL; 12 | 13 | Platform::Platform() { 14 | _eventTimer = new EventTimer(); 15 | Toolkit::g_instance = this; 16 | _timeStart = System::millisTicks(); 17 | } 18 | Platform::~Platform() { 19 | delete _eventTimer; 20 | } 21 | 22 | double Platform::getGameTime() { 23 | return System::millisTicks() - _timeStart; 24 | } 25 | 26 | int Platform::run(Application* game, const char* title, int w, int h) { 27 | PlatformGlfw* platform = new PlatformGlfw(); 28 | Platform::_cur = platform; 29 | platform->_game = game; 30 | 31 | GP_ASSERT(game); 32 | platform->init(title, w, h); 33 | int result = platform->enterMessagePump(); 34 | 35 | #ifndef __EMSCRIPTEN__ 36 | platform->signalShutdown(); 37 | delete platform; 38 | #endif 39 | return result; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /modules/ui/Button.h: -------------------------------------------------------------------------------- 1 | #ifndef BUTTON_H_ 2 | #define BUTTON_H_ 3 | 4 | #include "Container.h" 5 | #include "Label.h" 6 | #include "Theme.h" 7 | #include "base/Properties.h" 8 | 9 | namespace mgp 10 | { 11 | 12 | /** 13 | * Defines a button control. 14 | * 15 | * @see http://gameplay3d.github.io/GamePlay/docs/file-formats.html#wiki-UI_Forms 16 | */ 17 | class Button : public Label 18 | { 19 | friend class Control; 20 | protected: 21 | 22 | /** 23 | * Constructor. 24 | */ 25 | Button(); 26 | 27 | /** 28 | * Destructor. 29 | */ 30 | virtual ~Button(); 31 | 32 | /** 33 | * Gets the data binding index for this control. 34 | * 35 | * @return The data binding index for control. 36 | */ 37 | const unsigned int getDataBinding() const; 38 | 39 | /** 40 | * Sets the data binding provider for this control. 41 | * 42 | * @param dataBinding The data binding index for control. 43 | */ 44 | void setDataBinding(unsigned int dataBinding); 45 | 46 | private: 47 | 48 | /** 49 | * Constructor. 50 | */ 51 | Button(const Button& copy); 52 | 53 | unsigned int _dataBinding; 54 | 55 | }; 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /res/shaders/deferred/colored.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | 10 | /////////////////////////////////////////////////////////// 11 | uniform vec4 u_diffuseColor; 12 | uniform sampler2D u_lightAcc; 13 | uniform vec2 u_viewport; 14 | 15 | #if defined(VERTEX_COLOR) 16 | in vec3 v_color; 17 | #endif 18 | 19 | out vec4 FragColor; 20 | 21 | #include "../_common.frag" 22 | 23 | void main() 24 | { 25 | #if defined(CLIP_PLANE) 26 | if(v_clipDistance < 0.0) discard; 27 | #endif 28 | 29 | vec4 _baseColor; 30 | 31 | #if defined(VERTEX_COLOR) 32 | _baseColor = vec4(v_color, 1.0); 33 | #else 34 | _baseColor = u_diffuseColor; 35 | #endif 36 | vec2 viewport = textureSize(u_lightAcc, 0); 37 | vec2 texCoord = vec2(gl_FragCoord.x / viewport.x, gl_FragCoord.y / viewport.y); 38 | 39 | vec4 lightAcc = texture(u_lightAcc, texCoord); 40 | vec3 specularAcc = lightAcc.rgb; 41 | vec3 diffuseAcc = lightAcc.a * _baseColor.rgb; 42 | 43 | FragColor.rgb = specularAcc + diffuseAcc; 44 | FragColor.a = _baseColor.a; 45 | 46 | applyCommonFrag(); 47 | } 48 | -------------------------------------------------------------------------------- /res/shaders/postEffect/gaussianBlur.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | out vec4 FragColor; 10 | in vec2 v_texCoord; 11 | 12 | uniform sampler2D u_texture; 13 | 14 | float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); 15 | 16 | void main() 17 | { 18 | vec2 tex_offset = 1.0 / textureSize(u_texture, 0); // gets size of single texel 19 | vec3 result = texture(u_texture, v_texCoord).rgb * weight[0]; // current fragment's contribution 20 | 21 | #ifdef GAUSS_HORIZONTAL 22 | for(int i = 1; i < 5; ++i) 23 | { 24 | result += texture(u_texture, v_texCoord + vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; 25 | result += texture(u_texture, v_texCoord - vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; 26 | } 27 | #else 28 | for(int i = 1; i < 5; ++i) 29 | { 30 | result += texture(u_texture, v_texCoord + vec2(0.0, tex_offset.y * i)).rgb * weight[i]; 31 | result += texture(u_texture, v_texCoord - vec2(0.0, tex_offset.y * i)).rgb * weight[i]; 32 | } 33 | #endif 34 | FragColor = vec4(result, 1.0); 35 | } -------------------------------------------------------------------------------- /example/Qt/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 600 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 0 30 | 0 31 | 800 32 | 17 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | MgpView 41 | QOpenGLWidget 42 |
mgpview.h
43 |
44 |
45 | 46 | 47 |
48 | -------------------------------------------------------------------------------- /modules/render/Shadow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef SHADOW_H 9 | #define SHADOW_H 10 | 11 | #include "FrameBuffer.h" 12 | #include "scene/Camera.h" 13 | #include "scene/Light.h" 14 | 15 | namespace mgp 16 | { 17 | class Scene; 18 | class Renderer; 19 | class Material; 20 | 21 | class Shadow : public Refable { 22 | 23 | Material* _material; 24 | int _cascadeCount; 25 | int _cascadeTextureSize; 26 | public: 27 | struct CascadeInfo { 28 | float distance; 29 | Matrix lightSpaceMatrix; 30 | }; 31 | private: 32 | FrameBuffer* _frameBuffer = NULL; 33 | std::vector _cascades; 34 | 35 | public: 36 | Shadow(); 37 | ~Shadow(); 38 | void update(Scene* scene, Renderer *renderer, Light* light, Camera* curCamera); 39 | CascadeInfo& getCascade(int i) { return _cascades[i]; } 40 | int getCascadeCount() { return _cascadeCount; } 41 | FrameBuffer* getFrameBuffer() { return _frameBuffer; } 42 | private: 43 | void initCascadeDistance(Camera* curCamera); 44 | void draw(Scene* scene, Renderer* renderer, Matrix& lightView, Matrix& lightProjection, CascadeInfo& cascade, int index); 45 | }; 46 | } 47 | 48 | #endif -------------------------------------------------------------------------------- /res/shaders/textured.vert: -------------------------------------------------------------------------------- 1 | 2 | #include "_lighting_def.glsl" 3 | 4 | /////////////////////////////////////////////////////////// 5 | 6 | uniform mat4 u_projectionMatrix; 7 | 8 | #if defined(TEXTURE_REPEAT) 9 | uniform vec2 u_textureRepeat; 10 | #endif 11 | 12 | #if defined(TEXTURE_OFFSET) 13 | uniform vec2 u_textureOffset; 14 | #endif 15 | 16 | /////////////////////////////////////////////////////////// 17 | in vec3 a_position; 18 | in vec2 a_texCoord; 19 | 20 | out vec2 v_texCoord; 21 | 22 | /////////////////////////////////////////////////////////// 23 | 24 | #if defined(SKINNING) 25 | #include "_skinning.vert" 26 | #else 27 | #include "_skinning-none.vert" 28 | #endif 29 | 30 | #if defined(LIGHTING) 31 | #include "_lighting.vert" 32 | #endif 33 | 34 | #include "_common.vert" 35 | 36 | void main() 37 | { 38 | vec4 position = getPosition(); 39 | 40 | gl_Position = u_projectionMatrix * position; 41 | 42 | #if defined(LIGHTING) 43 | applyLight(position); 44 | #endif 45 | 46 | v_texCoord = a_texCoord; 47 | 48 | #if defined(TEXTURE_REPEAT) 49 | v_texCoord *= u_textureRepeat; 50 | #endif 51 | 52 | #if defined(TEXTURE_OFFSET) 53 | v_texCoord += u_textureOffset; 54 | #endif 55 | 56 | applyCommonVert(); 57 | } 58 | -------------------------------------------------------------------------------- /modules/ui/Layout.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "Layout.h" 3 | #include "Control.h" 4 | #include "Container.h" 5 | #include "platform/Toolkit.h" 6 | 7 | namespace mgp 8 | { 9 | 10 | float Layout::prefContentWidth(const Container* container) { 11 | // Size ourself to tightly fit the width of our children 12 | float width = 0; 13 | for (size_t i = 0, count = container->getControls().size(); i < count; ++i) 14 | { 15 | Control* ctrl = container->getControls()[i]; 16 | if (ctrl->isVisible() && !ctrl->isWidthPercentage()) 17 | { 18 | float w = ctrl->getMeasureBufferedWidth(); 19 | if (width < w) 20 | width = w; 21 | } 22 | } 23 | return width; 24 | } 25 | 26 | float Layout::prefContentHeight(const Container* container) { 27 | // Size ourself to tightly fit the height of our children 28 | float height = 0; 29 | for (size_t i = 0, count = container->getControls().size(); i < count; ++i) 30 | { 31 | Control* ctrl = container->getControls()[i]; 32 | if (ctrl->isVisible() && !ctrl->isHeightPercentage()) 33 | { 34 | float h = ctrl->getMeasureBufferedHeight(); 35 | if (height < h) 36 | height = h; 37 | } 38 | } 39 | return height; 40 | } 41 | } -------------------------------------------------------------------------------- /core/base/Serializable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Serializer.h" 4 | #include 5 | #include "Ref.h" 6 | 7 | namespace mgp 8 | { 9 | 10 | /** 11 | * Defines a object that can be read(deserialized) and written(serailized) to file. 12 | * 13 | * For object encoding/compatibility, properties must be serialized in the same 14 | * order there are deserialized. 15 | */ 16 | class Serializable 17 | { 18 | public: 19 | 20 | /** 21 | * Destructor 22 | */ 23 | virtual ~Serializable() { } 24 | 25 | /** 26 | * Gets the class name string for the object. 27 | * 28 | * This is used by the Serializer when reading/writing objects. 29 | * The class name should be namespaced. Ex: mgp::SceneObject 30 | */ 31 | virtual std::string getClassName() { return ""; } 32 | 33 | /** 34 | * Event handled when an object is asked to serialize itself. 35 | * 36 | * @param serializer The serializer to write properties to. 37 | */ 38 | virtual void onSerialize(Serializer* serializer) { } 39 | 40 | /** 41 | * Event handled when an object properties are being deserialized. 42 | * 43 | * @param serializer The serializer to read properties from. 44 | */ 45 | virtual void onDeserialize(Serializer* serializer) { } 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /doc/arch.md: -------------------------------------------------------------------------------- 1 | ## 整体结构 2 | 3 | mgpCore模块包括基础库、场景定义等。 4 | 5 | mgpModules模块包括渲染、GUI、声音、物理等功能。除渲染外,很多都是可选的功能。 6 | 7 | mgpPro模块包括网络、定制的图形绘制等功能,暂时没有开源。 8 | 9 | 再往上的游戏编辑器、FastEarth地图引擎等都是独立的项目,依赖mgp。 10 | 11 | ## 第三方库 12 | 尽管极力避免使用第三方库,但仍然有很多。 13 | 14 | - glfw:提供窗口系统 15 | - stb_image: 提供图片解码 16 | - freetype:提供文字渲染 17 | - Bullet:物理引擎 18 | - miniaudio:声音库 19 | - draco:压缩库(可选) 20 | - jsonc:json库 21 | - wase: GUI库 22 | 23 | 通过websemmbly编译到web平台时,几乎不依赖第三方库,所有功能都优先用浏览器提供的。 24 | 25 | ## 场景组成 26 | 27 | ![image](scene.png) 28 | 29 | Scene内是Node组成的树状结构。空间变换矩阵信息存储在Node中。每个Node包含多个Component,Component有多种实现。 30 | 31 | Drawable表示可渲染的对象。其中Model包含Mesh和Material,分别表示几何和渲染样式。 32 | 33 | ## 动画系统 34 | 35 | 动画的依赖关系比较别扭,所以单独记录一下。 36 | 37 | ![image](animation.png) 38 | 39 | 动画里面AnimationController负责多个动画的运行和更新。AnimationClip表示动画的片段,负责记录动画的执行状态。AnimationClip有start和stop方法负责动画的执行和停止。 40 | 41 | Animation代表一个动画,是多个AnimationChannel的组合。Animation有一个默认的AnimationClip,可以创建新的AnimationClip。 42 | 43 | 但AnimationChannel反过来持有Animation的所有权,这个地方有些怪异。AnimationChannel包含一个Curve对象来存储实际的关键帧数据。 44 | 45 | AnimationTarget是动画的目标对象,其他想动的对象继承自它。AnimationTarget引用AnimationChannel,而不是Animation。 46 | 47 | ## 渲染流程 48 | 49 | 渲染流程在RenderPath内执行,RenderPath包含多个RenderStage。RenderStage是一组渲染过程。前向渲染和延迟渲染是RenderStage的不同组合来实现的。 50 | 51 | 通过Renderer接口提供图形功能的封装,不直接依赖OpenGL,方便后期切换到其他图形API。 52 | 53 | -------------------------------------------------------------------------------- /doc/gltf.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 加载GLTF模型 4 | 5 | 只支持gltf格式导入,其他格式模型转换为gltf格式数据。 6 | 7 | ``` 8 | GltfLoader loader; 9 | loader.lighting = true; //是否启用光照 10 | auto _scene = loader.load("res/gltf/car.gltf"); 11 | ``` 12 | 13 | 默认构建不支持draco压缩,如果需要draco支持,需要使用fmake_full.props来构建。 14 | 15 | ## 动画 16 | 17 | 支持骨骼蒙皮动画和变形动画。有两种方式运行动画。 18 | 19 | 1.通过模型获取: 20 | ``` 21 | Node* node = _scene->findNode("Cesium_Man"); 22 | Model* model = dynamic_cast(node->getDrawable()); 23 | 24 | Animation* animation = model->getSkin()->getRootJoint()->getAnimation(); 25 | AnimationClip* clip = animation->getClip(); 26 | clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE); 27 | clip->play(); 28 | ``` 29 | 30 | 2.通过场景获取 31 | ``` 32 | if (_scene->getAnimations().size() > 0) { 33 | Animation* animation = _scene->getAnimations()[0]; 34 | AnimationClip* clip = animation->getClip(); 35 | clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE); 36 | clip->play(); 37 | } 38 | ``` 39 | 40 | 默认情况下,骨骼节点是不加入主场景中的。 41 | 42 | ## 实例化渲染 43 | 44 | 通过clone方法创建一个模型的多个实例 45 | 46 | ``` 47 | NodeCloneContext ctx; 48 | UPtr _model2 = model->clone(ctx); 49 | 50 | Node* modelNode2 = _scene->addNode("model2"); 51 | modelNode2->setDrawable(std::move(_model2)); 52 | modelNode2->translate(1, 0, 0); 53 | ``` 54 | -------------------------------------------------------------------------------- /core/scene/AssetManager.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSETMANAGER_H 2 | #define ASSETMANAGER_H 3 | 4 | #include "base/Base.h" 5 | #include "base/Ref.h" 6 | #include "base/Ptr.h" 7 | #include 8 | #include "base/Resource.h" 9 | 10 | namespace mgp 11 | { 12 | class AssetManager 13 | { 14 | public: 15 | enum ResType { 16 | rt_texture, 17 | rt_materail, 18 | //rt_shaderProgram, 19 | rt_mesh, 20 | rt_animation, 21 | rt_skin, 22 | rt_count 23 | }; 24 | private: 25 | std::map resourceMap[rt_count]; 26 | std::recursive_mutex _mutex; 27 | std::string path; 28 | std::map _saved; 29 | public: 30 | static AssetManager *getInstance(); 31 | static void releaseInstance(); 32 | private: 33 | AssetManager(); 34 | ~AssetManager(); 35 | 36 | public: 37 | void setPath(const std::string& path); 38 | const std::string& getPath(); 39 | void clear(); 40 | void beginSave(); 41 | 42 | template 43 | UPtr load(const std::string &name, ResType type, bool cache = true) { 44 | return load(name, type, cache).dynamicCastTo(); 45 | } 46 | 47 | UPtr load(const std::string &name, ResType type, bool cache = true); 48 | 49 | void remove(const std::string &name, ResType type); 50 | 51 | void save(Resource*res); 52 | }; 53 | } 54 | #endif // ASSETMANAGER_H 55 | -------------------------------------------------------------------------------- /doc/material.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 材质 4 | 5 | 创建材质 6 | ``` 7 | //创建并赋值给model 8 | _model->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "LIGHTING;PBR;IBL;LDR"); 9 | 10 | //直接创建 11 | Material::create("res/shaders/colored.vert", "res/shaders/colored.frag", "LIGHTING;PBR;IBL;LDR"); 12 | ``` 13 | 14 | 只支持GLSL。第三个参数为shader里面的宏定义,中间用分号分隔。 15 | 16 | ### 材质参数 17 | 18 | 目前材质参数使用字符串定义和shader里面的变量名相同。常见的PBR参数如下: 19 | ``` 20 | material->getParameter("u_diffuseColor")->setVector4(Vector4(0.5, 0.0, 0.0, 1.0)); 21 | material->getParameter("u_albedo")->setVector3(Vector3(0.5, 0.0, 0.0)); 22 | material->getParameter("u_metallic")->setFloat(metalness); 23 | material->getParameter("u_roughness")->setFloat(roughness); 24 | material->getParameter("u_ao")->setFloat(1.0); 25 | material->getParameter("u_emissive")->setVector3(Vector3(0.0, 0.0, 0.0)); 26 | ``` 27 | 28 | 29 | ### 纹理 30 | 31 | ``` 32 | Texture* sampler = material->getParameter("u_diffuseTexture")->setValue("res/image/crate.png", true); 33 | sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR); 34 | ``` 35 | 36 | 37 | ### 半透明 38 | 半透明效果需要设置多个地方: 39 | 40 | 1. 材质颜色alpha小于1.0, 例如: 41 | ``` 42 | material->getParameter("u_diffuseColor")->setVector4(Vector4(1.0, 0.5, 0.5, 0.4)); 43 | ``` 44 | 45 | 2. 启用混合 46 | ``` 47 | material->getStateBlock()->setBlend(true); 48 | ``` 49 | 50 | 3. 在半透明层绘制 51 | ``` 52 | _model->setRenderLayer(Drawable::Transparent); 53 | ``` 54 | -------------------------------------------------------------------------------- /core/base/Buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | #ifndef FILESTREAM_H_ 11 | #define FILESTREAM_H_ 12 | 13 | #include "Stream.h" 14 | 15 | namespace mgp 16 | { 17 | 18 | /** 19 | * ByteArray is memory buffer 20 | */ 21 | class Buffer : public Stream { 22 | private: 23 | uint8_t* data; 24 | size_t _pos; 25 | size_t _size; 26 | bool owner; 27 | 28 | public: 29 | Buffer(); 30 | Buffer(size_t size); 31 | Buffer(uint8_t* data, size_t size, bool owner); 32 | ~Buffer(); 33 | 34 | //virtual ssize_t write(const char *buf, size_t size) override; 35 | //virtual ssize_t read(char *buf, size_t size) override; 36 | 37 | void readSlice(Buffer &out, bool copy); 38 | 39 | //read Data no copy 40 | unsigned char * readDirect(int len); 41 | unsigned char *getData() { return data; } 42 | 43 | size_t remaining() { return _size - _pos; } 44 | 45 | virtual size_t read(void* ptr, size_t size, size_t count); 46 | virtual size_t write(const void* ptr, size_t size, size_t count); 47 | virtual size_t length() { return _size; } 48 | virtual long int position() { return _pos; } 49 | virtual bool seek(long int offset, int origin = SEEK_SET); 50 | }; 51 | 52 | 53 | } 54 | 55 | #endif -------------------------------------------------------------------------------- /modules/ui/ModalLayer.cpp: -------------------------------------------------------------------------------- 1 | #include "ModalLayer.h" 2 | #include "Form.h" 3 | 4 | using namespace mgp; 5 | 6 | ModalLayer::ModalLayer() 7 | { 8 | setPadding(0, 0, 0, 0); 9 | setLayout(Layout::LAYOUT_ABSOLUTE); 10 | this->setVisible(false); 11 | _className = "ModalLayer"; 12 | } 13 | 14 | ModalLayer::~ModalLayer() 15 | { 16 | } 17 | 18 | void ModalLayer::controlEvent(Listener::EventType evt) { 19 | if (evt == Listener::CLICK) { 20 | if (_modal < 2) { 21 | pop(); 22 | } 23 | } 24 | } 25 | 26 | unsigned int ModalLayer::draw(Form* form, const Rectangle& clip, RenderInfo* view) { 27 | form->flushBatch(view); 28 | return Container::draw(form, clip, view); 29 | } 30 | 31 | 32 | void ModalLayer::add(Control* content, int modal) { 33 | GP_ASSERT(content); 34 | addControl(uniqueFromInstant(content)); 35 | 36 | this->setVisible(true); 37 | _modal = modal; 38 | setConsumeInputEvents(_modal > 0); 39 | } 40 | 41 | void ModalLayer::pop() { 42 | int n = getControlCount(); 43 | if (n > 0) { 44 | removeControl(n - 1); 45 | if (n == 1) { 46 | this->setVisible(false); 47 | } 48 | } 49 | } 50 | 51 | void ModalLayer::remove(Control* content) { 52 | int n = getControlCount(); 53 | if (n > 0) { 54 | removeControl(content); 55 | if (n == 1) { 56 | this->setVisible(false); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /res/shaders/postEffect/edgeDetect.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | in vec2 v_texCoord; 6 | uniform vec4 u_diffuseColor; 7 | 8 | out vec4 fragColor; 9 | 10 | uniform sampler2D u_texture; 11 | uniform float u_filter; 12 | 13 | float luminance(vec4 color) { 14 | return color.a == 0.0 ? 0.0 : 1.0; 15 | //return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; 16 | } 17 | 18 | void main() { 19 | vec2 texelSize = 1.0 / vec2(textureSize(u_texture, 0)); 20 | float resultX = 0.0; 21 | float resultY = 0.0; 22 | 23 | float sobelX[9] = float[9]( 24 | -1.0, 0.0, 1.0, 25 | -2.0, 0.0, 2.0, 26 | -1.0, 0.0, 1.0 27 | ); 28 | 29 | float sobelY[9] = float[9]( 30 | -1.0, -2.0, -1.0, 31 | 0.0, 0.0, 0.0, 32 | 1.0, 2.0, 1.0 33 | ); 34 | 35 | for (int y = -1; y <= 1; y++) 36 | { 37 | for (int x = -1; x <= 1; x++) 38 | { 39 | vec2 offset = vec2(float(x), float(y)) * texelSize; 40 | float value = luminance(texture(u_texture, v_texCoord + offset)); 41 | 42 | int sobelPos = (x+1) + (y+1) * 3; 43 | resultX += value * sobelX[sobelPos]; 44 | resultY += value * sobelY[sobelPos]; 45 | } 46 | } 47 | 48 | float edgeValue = sqrt((resultX * resultX) + (resultY * resultY)); 49 | vec4 edgeColor = (u_filter < edgeValue) ? u_diffuseColor : vec4(0.0); 50 | 51 | fragColor = edgeColor; 52 | } -------------------------------------------------------------------------------- /modules/ui/AbsoluteLayout.h: -------------------------------------------------------------------------------- 1 | #ifndef ABSOLUTELAYOUT_H_ 2 | #define ABSOLUTELAYOUT_H_ 3 | 4 | #include "Layout.h" 5 | 6 | namespace mgp 7 | { 8 | 9 | /** 10 | * Defines a Layout for forms and containers that requires the user 11 | * to specify absolute positions for all contained controls. 12 | */ 13 | class AbsoluteLayout : public Layout 14 | { 15 | //friend class Form; 16 | //friend class Container; 17 | 18 | public: 19 | 20 | /** 21 | * Get the type of this Layout. 22 | * 23 | * @return Layout::LAYOUT_ABSOLUTE 24 | */ 25 | Layout::Type getType(); 26 | 27 | /** 28 | * Create an AbsoluteLayout. 29 | * 30 | * @return An AbsoluteLayout object. 31 | */ 32 | static UPtr create(); 33 | protected: 34 | 35 | /** 36 | * Update the controls contained by the specified container. 37 | * 38 | * An AbsoluteLayout does nothing to modify the layout of controls. 39 | * It simply calls update() on any control that is dirty. 40 | * 41 | * @param container The container to update. 42 | */ 43 | void update(const Container* container); 44 | 45 | private: 46 | 47 | /* 48 | * Constructor. 49 | */ 50 | AbsoluteLayout(); 51 | 52 | /* 53 | * Constructor. 54 | */ 55 | AbsoluteLayout(const AbsoluteLayout& copy); 56 | 57 | /* 58 | * Destructor. 59 | */ 60 | virtual ~AbsoluteLayout(); 61 | 62 | 63 | }; 64 | 65 | } 66 | 67 | #endif -------------------------------------------------------------------------------- /modules/audio/AudioController.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIOCONTROLLER_H_ 2 | #define AUDIOCONTROLLER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct ma_engine; 9 | 10 | namespace mgp 11 | { 12 | 13 | class AudioListener; 14 | class AudioSource; 15 | 16 | /** 17 | * Defines a class for controlling game audio. 18 | */ 19 | class AudioController 20 | { 21 | friend class Application; 22 | friend class AudioSource; 23 | 24 | public: 25 | 26 | /** 27 | * Destructor. 28 | */ 29 | virtual ~AudioController(); 30 | 31 | static AudioController* cur(); 32 | 33 | bool isValid(); 34 | private: 35 | 36 | /** 37 | * Constructor. 38 | */ 39 | AudioController(); 40 | 41 | /** 42 | * Controller initialize. 43 | */ 44 | void initialize(); 45 | 46 | /** 47 | * Controller finalize. 48 | */ 49 | void finalize(); 50 | 51 | /** 52 | * Controller pause. 53 | */ 54 | void pause(); 55 | 56 | /** 57 | * Controller resume. 58 | */ 59 | void resume(); 60 | 61 | /** 62 | * Controller update. 63 | */ 64 | void update(float elapsedTime); 65 | 66 | void addPlayingSource(AudioSource* source); 67 | 68 | void removePlayingSource(AudioSource* source); 69 | 70 | ma_engine* _engine; 71 | std::set _playingSources; 72 | std::set _streamingSources; 73 | AudioSource* _pausingSource; 74 | }; 75 | 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /res/shaders/textured.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | /////////////////////////////////////////////////////////// 10 | // Uniforms 11 | uniform sampler2D u_diffuseTexture; 12 | 13 | #if defined(DIFFUSE_COLOR) 14 | uniform vec4 u_diffuseColor; 15 | #endif 16 | 17 | /////////////////////////////////////////////////////////// 18 | // Varyings 19 | in vec2 v_texCoord; 20 | 21 | out vec4 FragColor; 22 | 23 | /////////////////////////////////////////////////////////// 24 | // Variables 25 | vec4 _baseColor; 26 | 27 | #define ALBEDO_MAP 28 | 29 | #include "_common.frag" 30 | 31 | #include "_lighting_def.glsl" 32 | #if defined(LIGHTING) 33 | #include "_lighting.frag" 34 | #endif 35 | 36 | #ifdef TEXTURE_DISCARD_ALPHA 37 | uniform float u_alphaCutoff; 38 | #endif 39 | 40 | void main() 41 | { 42 | #if defined(CLIP_PLANE) 43 | if(v_clipDistance < 0.0) discard; 44 | #endif 45 | 46 | _baseColor = texture(u_diffuseTexture, v_texCoord); 47 | #if defined(DIFFUSE_COLOR) 48 | _baseColor = _baseColor * u_diffuseColor; 49 | #endif 50 | 51 | FragColor.a = _baseColor.a; 52 | 53 | #if defined(TEXTURE_DISCARD_ALPHA) 54 | if (FragColor.a < u_alphaCutoff) 55 | discard; 56 | #endif 57 | 58 | #if defined(LIGHTING) 59 | FragColor.rgb = getLitPixel(); 60 | #else 61 | FragColor.rgb = _baseColor.rgb; 62 | #endif 63 | 64 | applyCommonFrag(); 65 | } 66 | -------------------------------------------------------------------------------- /modules/app/InputListener.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUTLISTENER_H_ 2 | #define INPUTLISTENER_H_ 3 | 4 | #include "platform/Keyboard.h" 5 | #include "platform/Mouse.h" 6 | 7 | namespace mgp { 8 | class InputListener { 9 | public: 10 | /** 11 | * Keyboard callback on keyPress events. 12 | * 13 | * @param evt The key event that occurred. 14 | * @param key If evt is KEY_PRESS or KEY_RELEASE then key is the key code from Keyboard::Key. 15 | * If evt is KEY_CHAR then key is the unicode value of the character. 16 | * 17 | * @see Keyboard::KeyEvent 18 | * @see Keyboard::Key 19 | */ 20 | virtual bool keyEvent(Keyboard key) { return false; } 21 | 22 | /** 23 | * Mouse callback on mouse events. If the game does not consume the mouse move event or left mouse click event 24 | * then it is interpreted as a touch event instead. 25 | * 26 | * @param evt The mouse event that occurred. 27 | * @param x The x position of the mouse in pixels. Left edge is zero. 28 | * @param y The y position of the mouse in pixels. Top edge is zero. 29 | * @param wheelDelta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward). 30 | * 31 | * @return True if the mouse event is consumed or false if it is not consumed. 32 | * 33 | * @see MotionEvent::MotionType 34 | */ 35 | virtual bool mouseEvent(Mouse evt) { return false; } 36 | 37 | virtual void onSetup() {} 38 | virtual void onTeardown() {} 39 | }; 40 | } 41 | 42 | 43 | #endif -------------------------------------------------------------------------------- /core/base/System.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | 11 | #ifndef TimeUtil_hpp 12 | #define TimeUtil_hpp 13 | 14 | #include 15 | 16 | namespace mgp { 17 | 18 | typedef int64_t NanosTime; 19 | typedef int64_t MillisTime; 20 | 21 | namespace System { 22 | /*======================================================================== 23 | * Time 24 | */ 25 | const int64_t NanoPerSecond = 1000000000L; 26 | 27 | /** 28 | * return the milliseconds from midnight, January 1, 1970 UTC. 29 | */ 30 | MillisTime currentTimeMillis(); 31 | 32 | /** 33 | * returns a relative time. 34 | * Typically it is the number of nanosecond ticks which have elapsed since system startup. 35 | */ 36 | NanosTime nanoTicks(); 37 | 38 | inline MillisTime millisTicks() { return nanoTicks()/1000000L; } 39 | 40 | /*======================================================================== 41 | * Thread 42 | */ 43 | /** 44 | * sleep current thread millitm second 45 | */ 46 | void sleep(MillisTime millitm); 47 | 48 | /** 49 | * get current execable file path 50 | */ 51 | bool getSelfPath(char *selfname); 52 | 53 | /** 54 | * Thread ID 55 | */ 56 | uint64_t currentThreadId(); 57 | 58 | } 59 | 60 | } 61 | #endif /* TimeUtil_hpp */ 62 | -------------------------------------------------------------------------------- /core/objects/FontEngine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef FONTFACE_H_ 9 | #define FONTFACE_H_ 10 | 11 | #include "objects/SpriteBatch.h" 12 | 13 | 14 | namespace mgp { 15 | 16 | struct FontInfo { 17 | char name[128]; 18 | float size; 19 | int bold; 20 | float outline; 21 | 22 | FontInfo() : size(30), bold(1), outline(1) { name[0] = 0; } 23 | }; 24 | 25 | struct GlyphMetrics { 26 | float width; 27 | float height; 28 | 29 | float horiBearingX; 30 | float horiBearingY; 31 | float horiAdvance; 32 | 33 | float vertBearingX; 34 | float vertBearingY; 35 | float vertAdvance; 36 | 37 | void scaleMetrics(float scale); 38 | }; 39 | 40 | struct Glyph { 41 | GlyphMetrics metrics; 42 | int code; 43 | int imgX; 44 | int imgY; 45 | int imgW; 46 | int imgH; 47 | float imgScale; 48 | unsigned char* imgData; 49 | int texture; 50 | int imgPadding; 51 | }; 52 | 53 | 54 | class FontFace { 55 | void* library; 56 | void* face; 57 | 58 | std::map kerningCache; 59 | std::map metricsCache; 60 | public: 61 | typedef uint32_t Char; 62 | FontFace(); 63 | ~FontFace(); 64 | bool load(const char* file); 65 | bool renderChar(Char ch, FontInfo& font, int fontSize, Glyph& glyph); 66 | 67 | float getKerning(FontInfo& font, Char previous, Char current); 68 | bool merics(Char ch, FontInfo& font, GlyphMetrics& m); 69 | }; 70 | 71 | 72 | } 73 | 74 | 75 | #endif -------------------------------------------------------------------------------- /res/shaders/_morph.vert: -------------------------------------------------------------------------------- 1 | 2 | uniform float u_morphWeights[MORPH_TARGET_COUNT]; 3 | 4 | #if MORPH_TARGET_COUNT > 0 5 | in vec3 a_morphTarget0; 6 | #endif 7 | #if MORPH_TARGET_COUNT > 1 8 | in vec3 a_morphTarget1; 9 | #endif 10 | #if MORPH_TARGET_COUNT > 2 11 | in vec3 a_morphTarget2; 12 | #endif 13 | #if MORPH_TARGET_COUNT > 3 14 | in vec3 a_morphTarget3; 15 | #endif 16 | #if MORPH_TARGET_COUNT > 4 17 | in vec3 a_morphTarget4; 18 | #endif 19 | #if MORPH_TARGET_COUNT > 5 20 | in vec3 a_morphTarget5; 21 | #endif 22 | #if MORPH_TARGET_COUNT > 6 23 | in vec3 a_morphTarget6; 24 | #endif 25 | #if MORPH_TARGET_COUNT > 7 26 | in vec3 a_morphTarget7; 27 | #endif 28 | 29 | 30 | vec3 getMorphPosition(vec3 pos) { 31 | #if MORPH_TARGET_COUNT > 0 32 | pos += (u_morphWeights[0] * a_morphTarget0); 33 | #endif 34 | #if MORPH_TARGET_COUNT > 1 35 | pos += (u_morphWeights[1] * a_morphTarget1); 36 | #endif 37 | #if MORPH_TARGET_COUNT > 2 38 | pos += (u_morphWeights[2] * a_morphTarget2); 39 | #endif 40 | #if MORPH_TARGET_COUNT > 3 41 | pos += (u_morphWeights[3] * a_morphTarget3); 42 | #endif 43 | #if MORPH_TARGET_COUNT > 4 44 | pos += (u_morphWeights[4] * a_morphTarget4); 45 | #endif 46 | #if MORPH_TARGET_COUNT > 5 47 | pos += (u_morphWeights[5] * a_morphTarget5); 48 | #endif 49 | #if MORPH_TARGET_COUNT > 6 50 | pos += (u_morphWeights[6] * a_morphTarget6); 51 | #endif 52 | #if MORPH_TARGET_COUNT > 7 53 | pos += (u_morphWeights[7] * a_morphTarget7); 54 | #endif 55 | 56 | return pos; 57 | } 58 | -------------------------------------------------------------------------------- /modules/app/AppConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef APP_CONFIG_H_ 2 | #define APP_CONFIG_H_ 3 | 4 | #include "base/Base.h" 5 | #include "base/Ptr.h" 6 | #include "platform/Toolkit.h" 7 | #include "base/Serializable.h" 8 | 9 | namespace mgp 10 | { 11 | /** 12 | * Defines a splash screen. 13 | */ 14 | class SplashScreen 15 | { 16 | public: 17 | std::string url; 18 | float duration; 19 | }; 20 | 21 | /** 22 | * Application configuration. 23 | */ 24 | class AppConfig : public Serializable, public Refable 25 | { 26 | public: 27 | 28 | /** 29 | * Constructor 30 | */ 31 | AppConfig(); 32 | 33 | /** 34 | * Destructor 35 | */ 36 | ~AppConfig(); 37 | 38 | /** 39 | * @see Serializable::getClassName 40 | */ 41 | std::string getClassName(); 42 | 43 | /** 44 | * @see Serializable::onSerialize 45 | */ 46 | void onSerialize(Serializer* serializer); 47 | 48 | /** 49 | * @see Serializable::onDeserialize 50 | */ 51 | void onDeserialize(Serializer* serializer); 52 | 53 | /** 54 | * @see Activator::createObject 55 | */ 56 | static Serializable* createObject(); 57 | 58 | std::string title; 59 | int width; 60 | int height; 61 | bool fullscreen; 62 | bool vsync; 63 | size_t multisampling; 64 | bool validation; 65 | std::string homePath; 66 | std::vector splashScreens; 67 | std::string mainScene; 68 | }; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /core/math/Matrix.inl: -------------------------------------------------------------------------------- 1 | #include "math/Matrix.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline const Matrix4 Matrix4::operator+(const Matrix4& m) const 7 | { 8 | Matrix4 result(*this); 9 | result.add(m); 10 | return result; 11 | } 12 | 13 | inline Matrix4& Matrix4::operator+=(const Matrix4& m) 14 | { 15 | add(m); 16 | return *this; 17 | } 18 | 19 | inline const Matrix4 Matrix4::operator-(const Matrix4& m) const 20 | { 21 | Matrix4 result(*this); 22 | result.subtract(m); 23 | return result; 24 | } 25 | 26 | inline Matrix4& Matrix4::operator-=(const Matrix4& m) 27 | { 28 | subtract(m); 29 | return *this; 30 | } 31 | 32 | inline const Matrix4 Matrix4::operator-() const 33 | { 34 | Matrix4 m(*this); 35 | m.negate(); 36 | return m; 37 | } 38 | 39 | inline const Matrix4 Matrix4::operator*(const Matrix4& m) const 40 | { 41 | Matrix4 result(*this); 42 | result.multiply(m); 43 | return result; 44 | } 45 | 46 | inline Matrix4& Matrix4::operator*=(const Matrix4& m) 47 | { 48 | multiply(m); 49 | return *this; 50 | } 51 | 52 | inline Vector3& operator*=(Vector3& v, const Matrix4& m) 53 | { 54 | m.transformVector(&v); 55 | return v; 56 | } 57 | 58 | inline const Vector3 operator*(const Matrix4& m, const Vector3& v) 59 | { 60 | Vector3 x; 61 | m.transformVector(v, &x); 62 | return x; 63 | } 64 | 65 | inline Vector4& operator*=(Vector4& v, const Matrix4& m) 66 | { 67 | m.transformVector(&v); 68 | return v; 69 | } 70 | 71 | inline const Vector4 operator*(const Matrix4& m, const Vector4& v) 72 | { 73 | Vector4 x; 74 | m.transformVector(v, &x); 75 | return x; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /core/math/Math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_BASE_H_ 2 | #define MATH_BASE_H_ 3 | 4 | // Math 5 | #define MATH_DEG_TO_RAD(x) ((x) * 0.0174532925) 6 | #define MATH_RAD_TO_DEG(x) ((x)* 57.29577951) 7 | #define MATH_RANDOM_MINUS1_1() ((2.0*((Float)rand()/RAND_MAX))-1.0) // Returns a random Float between -1 and 1. 8 | #define MATH_RANDOM_0_1() ((Float)rand()/RAND_MAX) // Returns a random Float between 0 and 1. 9 | #define MATH_FLOAT_SMALL 1.0e-37 10 | #define MATH_TOLERANCE 2e-37 11 | #define MATH_E 2.71828182845904523536 12 | #define MATH_LOG10E 0.4342944819032518 13 | #define MATH_LOG2E 1.442695040888963387 14 | #define MATH_PI 3.14159265358979323846 15 | #define MATH_PIOVER2 1.57079632679489661923 16 | #define MATH_PIOVER4 0.785398163397448309616 17 | #define MATH_PIX2 6.28318530717958647693 18 | #define MATH_EPSILON 0.000001 19 | #define MATH_CLAMP(x, lo, hi) ((x < lo) ? lo : ((x > hi) ? hi : x)) 20 | #ifndef M_1_PI 21 | #define M_1_PI 0.31830988618379067154 22 | #endif 23 | 24 | typedef double Float; 25 | 26 | namespace mgp 27 | { 28 | /** 29 | * power of 2 meaning 2^n. 30 | * e.g. 2,4,8,16,... 31 | */ 32 | inline bool isPowerOf2(unsigned int x) { 33 | return !(x & (x-1)); 34 | } 35 | 36 | inline unsigned int nextPowerOf2(unsigned int x) { 37 | if ( isPowerOf2(x) ) return x; 38 | x |= x>>1; 39 | x |= x>>2; 40 | x |= x>>4; 41 | x |= x>>8; 42 | x |= x>>16; 43 | return x+1; 44 | } 45 | } 46 | 47 | #endif //MATH_BASE_H_ -------------------------------------------------------------------------------- /core/base/Serializer.cpp: -------------------------------------------------------------------------------- 1 | #include "Base.h" 2 | #include "Serializer.h" 3 | #include "SerializerBinary.h" 4 | #include "SerializerJson.h" 5 | #include "FileSystem.h" 6 | 7 | namespace mgp 8 | { 9 | 10 | Serializer::Serializer(Type type, Stream* stream, uint32_t versionMajor, uint32_t versionMinor) : 11 | _type(type), 12 | //_path(path), 13 | _stream(stream) 14 | { 15 | _version[0] = versionMajor; 16 | _version[1] = versionMinor; 17 | } 18 | 19 | Serializer::~Serializer() 20 | { 21 | _stream->close(); 22 | SAFE_DELETE(_stream); 23 | } 24 | 25 | UPtr Serializer::createReader(const std::string& path, bool isHiml) 26 | { 27 | Stream* stream = FileSystem::open(path.c_str()).take(); 28 | if (!stream) 29 | return UPtr(); 30 | 31 | UPtr serializer = SerializerBinary::create(stream); 32 | if (!serializer.get()) 33 | { 34 | stream->rewind(); 35 | serializer = SerializerJson::create(stream, isHiml); 36 | } 37 | return serializer; 38 | } 39 | 40 | UPtr Serializer::createReader(Stream* stream, bool isHiml) { 41 | UPtr serializer = SerializerBinary::create(stream); 42 | if (!serializer.get()) 43 | { 44 | stream->rewind(); 45 | serializer = SerializerJson::create(stream, isHiml); 46 | } 47 | return serializer; 48 | } 49 | 50 | //std::string Serializer::getPath() const 51 | //{ 52 | // return _path; 53 | //} 54 | 55 | uint32_t Serializer::getVersionMajor() const 56 | { 57 | return (uint32_t)_version[0]; 58 | } 59 | 60 | uint32_t Serializer::getVersionMinor() const 61 | { 62 | return (uint32_t)_version[1]; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /modules/app/CameraCtrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef CAMERACTRL_H_ 9 | #define CAMERACTRL_H_ 10 | 11 | #include "scene/Scene.h" 12 | #include "InputListener.h" 13 | 14 | namespace mgp { 15 | 16 | class CameraCtrl : public InputListener { 17 | public: 18 | virtual ~CameraCtrl() {} 19 | 20 | virtual void update(float elapsedTime) {} 21 | 22 | //virtual void touchEvent(MotionEvent& evt) {} 23 | 24 | virtual bool keyEvent(Keyboard evt) override { return false; } 25 | 26 | virtual bool mouseEvent(Mouse evt) override { return false; } 27 | }; 28 | 29 | class SceneView; 30 | class EditorCameraCtrl : public CameraCtrl { 31 | bool _isPressed = false; 32 | int _prevX; 33 | int _prevY; 34 | Camera* _camera; 35 | 36 | float _pitch; 37 | float _yaw; 38 | double _surfaceDistance; 39 | Vector3 _rotateCenter; 40 | bool _dirty = false; 41 | public: 42 | bool _reverseZoom = false; 43 | bool _autoRotateCenter = true; 44 | SceneView* sceneView; 45 | EditorCameraCtrl(); 46 | 47 | void setRotateCenter(const Vector3& c); 48 | 49 | void setRotate(float pitch, float yaw); 50 | void getRotate(float* pitch, float* yaw) { *pitch = _pitch; *yaw = _yaw; } 51 | 52 | void setCamera(Camera* camera) { _camera = camera; } 53 | 54 | void update(float elapsedTime); 55 | 56 | void touchEvent(MotionEvent& evt); 57 | 58 | bool keyEvent(Keyboard evt); 59 | 60 | bool mouseEvent(Mouse evt); 61 | 62 | private: 63 | bool updateSurfaceDistance(); 64 | }; 65 | 66 | } 67 | 68 | #endif -------------------------------------------------------------------------------- /res/shaders/font.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #extension GL_OES_standard_derivatives : enable 3 | #ifdef GL_FRAGMENT_PRECISION_HIGH 4 | precision highp float; 5 | #else 6 | precision mediump float; 7 | #endif 8 | #endif 9 | 10 | /////////////////////////////////////////////////////////// 11 | // Uniforms 12 | uniform sampler2D u_texture; 13 | 14 | #ifdef DISTANCE_FIELD 15 | uniform vec2 u_cutoff; 16 | #ifdef FONT_OUTLINE 17 | uniform vec2 u_outline; 18 | #endif 19 | #endif 20 | 21 | /////////////////////////////////////////////////////////// 22 | // Varyings 23 | in vec2 v_texCoord; 24 | in vec4 v_color; 25 | 26 | out vec4 FragColor; 27 | 28 | void main() 29 | { 30 | #ifdef DISTANCE_FIELD 31 | float distance = texture(u_texture, v_texCoord).r; 32 | //float smoothing = fwidth(distance); 33 | //float alpha = smoothstep(0.5 - smoothing * u_cutoff.x, 0.5 + smoothing * u_cutoff.y, distance); 34 | float alpha = smoothstep(u_cutoff.x-u_cutoff.y, u_cutoff.x+u_cutoff.y, distance); 35 | 36 | #ifdef FONT_OUTLINE 37 | vec4 outlineCol; 38 | outlineCol.a = smoothstep(u_outline.x-u_outline.y, u_outline.x+u_outline.y, distance); 39 | outlineCol.rgb = vec3(1.0, 1.0, 1.0) - v_color.rgb; 40 | FragColor.rgb = (outlineCol.rgb * outlineCol.a)*(1.0-alpha) + v_color.rgb * alpha; 41 | FragColor.a = (alpha + outlineCol.a*(1.0-alpha)) * v_color.a; 42 | #else 43 | FragColor = v_color; 44 | FragColor.a = alpha * v_color.a; 45 | #endif 46 | #else 47 | 48 | FragColor = v_color; 49 | FragColor.a = texture(u_texture, v_texCoord).a * v_color.a; 50 | 51 | #endif 52 | } -------------------------------------------------------------------------------- /modules/app/SceneView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef SCENEVIEW_H_ 9 | #define SCENEVIEW_H_ 10 | 11 | #include "base/Base.h" 12 | #include "scene/Renderer.h" 13 | #include "scene/Scene.h" 14 | #include "scene/Camera.h" 15 | #include "scene/Drawable.h" 16 | #include "render/RenderPath.h" 17 | #include "FirstPersonCamera.h" 18 | #include "CameraCtrl.h" 19 | 20 | namespace mgp { 21 | 22 | 23 | class SceneView { 24 | UPtr _scene; 25 | UPtr _camera; 26 | Rectangle _viewport; 27 | UPtr _renderPath; 28 | 29 | 30 | bool _useFirstPersonCamera = false; 31 | UPtr _cameraCtrl; 32 | 33 | public: 34 | SceneView(); 35 | ~SceneView(); 36 | 37 | void update(float elapsedTime); 38 | void render(); 39 | 40 | /** 41 | * Add a default Camera 42 | */ 43 | void initCamera(bool firstPerson, float nearPlane = 1.0f, float farPlane = 1000.0f, float fov = 45.0f); 44 | 45 | void finalize(); 46 | 47 | Rectangle* getViewport() { return &_viewport; } 48 | void setViewport(Rectangle* rect); 49 | Scene* getScene() { return _scene.get(); } 50 | void setScene(UPtr s) { _scene = std::move(s); } 51 | Camera* getCamera() { return _camera.get(); } 52 | void setCamera(Camera* s, bool initCameraCtrl = true); 53 | RenderPath* getRenderPath() { return _renderPath.get(); } 54 | void setRenderPath(UPtr s) { _renderPath = std::move(s); } 55 | 56 | CameraCtrl* getCameraCtrl() { return _cameraCtrl.get(); }; 57 | void setCameraCtrl(UPtr c); 58 | }; 59 | 60 | 61 | } 62 | 63 | #endif -------------------------------------------------------------------------------- /res/shaders/_common.frag: -------------------------------------------------------------------------------- 1 | 2 | #if defined(LIGHTMAP) 3 | uniform sampler2D u_lightmapTexture; 4 | in vec2 v_texCoord1; 5 | #endif 6 | 7 | #if defined(CLIP_PLANE) 8 | in float v_clipDistance; 9 | #endif 10 | 11 | #if defined(MODULATE_COLOR) 12 | uniform vec4 u_modulateColor; 13 | #endif 14 | 15 | #if defined(MODULATE_ALPHA) 16 | uniform float u_modulateAlpha; 17 | #endif 18 | 19 | #if defined(LINEARIZE_DEPTH) || defined(LINEARIZE_DEPTH_FUNC) || defined(SHADOW) 20 | uniform float u_nearPlane; 21 | uniform float u_farPlane; 22 | 23 | float linearizeDepth(float depth) 24 | { 25 | float z = depth * 2.0 - 1.0; 26 | return (2.0 * u_nearPlane * u_farPlane) / (u_farPlane + u_nearPlane - z * (u_farPlane - u_nearPlane)); 27 | } 28 | #endif 29 | 30 | //HDR to LDR 31 | vec3 hdrTonemapping(vec3 color) { 32 | return color / (color + vec3(1.0)); 33 | } 34 | 35 | // tone mapping 36 | vec3 hdrTonemapping2(vec3 hdrColor) { 37 | const float exposure = 1.0; 38 | return vec3(1.0) - exp(-hdrColor * exposure); 39 | } 40 | 41 | vec3 gammaCorrect(vec3 color) { 42 | return pow(color, vec3(1.0/2.2)); 43 | } 44 | 45 | void applyCommonFrag() { 46 | #if defined(LIGHTMAP) 47 | vec4 lightColor = texture(u_lightmapTexture, v_texCoord1); 48 | FragColor.rgb *= lightColor.rgb; 49 | #endif 50 | 51 | #if defined(LDR) 52 | vec3 color = FragColor.rgb; 53 | color = hdrTonemapping(color); 54 | color = gammaCorrect(color); 55 | FragColor.rgb = color; 56 | #endif 57 | 58 | #if defined(MODULATE_COLOR) 59 | FragColor *= u_modulateColor; 60 | #endif 61 | 62 | #if defined(MODULATE_ALPHA) 63 | FragColor.a *= u_modulateAlpha; 64 | #endif 65 | } -------------------------------------------------------------------------------- /core/math/Vector2.inl: -------------------------------------------------------------------------------- 1 | #include "math/Vector2.h" 2 | 3 | namespace mgp 4 | { 5 | 6 | inline const Vector2 Vector2::operator+(const Vector2& v) const 7 | { 8 | Vector2 result(*this); 9 | result.add(v); 10 | return result; 11 | } 12 | 13 | inline Vector2& Vector2::operator+=(const Vector2& v) 14 | { 15 | add(v); 16 | return *this; 17 | } 18 | 19 | inline const Vector2 Vector2::operator-(const Vector2& v) const 20 | { 21 | Vector2 result(*this); 22 | result.subtract(v); 23 | return result; 24 | } 25 | 26 | inline Vector2& Vector2::operator-=(const Vector2& v) 27 | { 28 | subtract(v); 29 | return *this; 30 | } 31 | 32 | inline const Vector2 Vector2::operator-() const 33 | { 34 | Vector2 result(*this); 35 | result.negate(); 36 | return result; 37 | } 38 | 39 | inline const Vector2 Vector2::operator*(Float x) const 40 | { 41 | Vector2 result(*this); 42 | result.scale(x); 43 | return result; 44 | } 45 | 46 | inline Vector2& Vector2::operator*=(Float x) 47 | { 48 | scale(x); 49 | return *this; 50 | } 51 | 52 | inline const Vector2 Vector2::operator/(const Float x) const 53 | { 54 | return Vector2(this->x / x, this->y / x); 55 | } 56 | 57 | inline bool Vector2::operator<(const Vector2& v) const 58 | { 59 | if (x == v.x) 60 | { 61 | return y < v.y; 62 | } 63 | return x < v.x; 64 | } 65 | 66 | inline bool Vector2::operator==(const Vector2& v) const 67 | { 68 | return x==v.x && y==v.y; 69 | } 70 | 71 | inline bool Vector2::operator!=(const Vector2& v) const 72 | { 73 | return x!=v.x || y!=v.y; 74 | } 75 | 76 | inline const Vector2 operator*(Float x, const Vector2& v) 77 | { 78 | Vector2 result(v); 79 | result.scale(x); 80 | return result; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /modules/app/PlatformGlfw.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_GLFW_H_ 2 | #define PLATFORM_GLFW_H_ 3 | 4 | #include "Platform.h" 5 | 6 | namespace mgp 7 | { 8 | class PlatformGlfw : public Platform { 9 | public: 10 | PlatformGlfw(); 11 | 12 | virtual void init(const char* title, int w, int h) override; 13 | virtual int enterMessagePump() override; 14 | virtual void swapBuffers() override; 15 | 16 | virtual void requestRepaint() override; 17 | virtual void signalShutdown() override; 18 | virtual bool canExit() override; 19 | virtual unsigned int getDisplayWidth(); 20 | virtual unsigned int getDisplayHeight(); 21 | virtual float getScreenScale() override; 22 | virtual bool isVsync() override; 23 | virtual void setVsync(bool enable) override; 24 | virtual void setMultiSampling(bool enabled) override; 25 | virtual bool isMultiSampling() override; 26 | virtual bool hasMouse() override; 27 | virtual void setMouseCaptured(bool captured) override; 28 | virtual bool isMouseCaptured() override; 29 | virtual void setCursorVisible(bool visible) override; 30 | virtual bool isCursorVisible() override; 31 | virtual bool hasAccelerometer() override; 32 | virtual void getAccelerometerValues(float* pitch, float* roll) override; 33 | virtual void getSensorValues(float* accelX, float* accelY, float* accelZ, float* gyroX, float* gyroY, float* gyroZ) override; 34 | virtual void getArguments(int* argc, char*** argv) override; 35 | virtual void displayKeyboard(bool display) override; 36 | virtual bool launchURL(const char* url) override; 37 | virtual std::string displayFileDialog(size_t mode, const char* title, const char* filterDescription, const char* filterExtensions, const char* initialDirectory) override; 38 | }; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /res/shaders/colored.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | #ifdef GL_FRAGMENT_PRECISION_HIGH 3 | precision highp float; 4 | #else 5 | precision mediump float; 6 | #endif 7 | #endif 8 | 9 | 10 | /////////////////////////////////////////////////////////// 11 | 12 | #if defined(MODULATE_COLOR) 13 | uniform vec4 u_modulateColor; 14 | #endif 15 | 16 | #if defined(MODULATE_ALPHA) 17 | uniform float u_modulateAlpha; 18 | #endif 19 | 20 | #if defined(VERTEX_COLOR) 21 | in vec3 v_color; 22 | #elif defined(VERTEX_COLOR4) 23 | in vec4 v_color; 24 | #else 25 | uniform vec4 u_diffuseColor; 26 | #endif 27 | 28 | /////////////////////////////////////////////////////////// 29 | 30 | vec4 _baseColor; 31 | 32 | out vec4 FragColor; 33 | 34 | /////////////////////////////////////////////////////////// 35 | 36 | #include "_common.frag" 37 | 38 | #include "_lighting_def.glsl" 39 | #if defined(LIGHTING) 40 | #include "_lighting.frag" 41 | #endif 42 | 43 | 44 | void main() 45 | { 46 | #if defined(CLIP_PLANE) 47 | if(v_clipDistance < 0.0) discard; 48 | #endif 49 | 50 | #if defined(LIGHTING) 51 | #if defined(VERTEX_COLOR) 52 | _baseColor.rgb = v_color; 53 | _baseColor.a = 1.0; 54 | #elif defined(VERTEX_COLOR4) 55 | _baseColor = v_color; 56 | #else 57 | _baseColor = u_diffuseColor; 58 | #endif 59 | FragColor.a = _baseColor.a; 60 | FragColor.rgb = getLitPixel(); 61 | #else 62 | #if defined(VERTEX_COLOR) 63 | FragColor.rgb = v_color; 64 | FragColor.a = 1.0; 65 | #elif defined(VERTEX_COLOR4) 66 | FragColor = v_color; 67 | #else 68 | FragColor = u_diffuseColor; 69 | #endif 70 | #endif 71 | 72 | applyCommonFrag(); 73 | } 74 | -------------------------------------------------------------------------------- /res/shaders/enviro.frag: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | uniform samplerCube u_skybox; 6 | uniform vec3 u_cameraPosition; 7 | 8 | uniform vec3 u_albedo; 9 | uniform float u_roughness; 10 | uniform float u_metallic; 11 | 12 | in vec3 v_position; 13 | in vec3 v_normalVector; 14 | out vec4 FragColor; 15 | 16 | 17 | 18 | const float textureOffset = 1.0 / 400.0; 19 | const float PI = 3.14159265359; 20 | 21 | vec3 fresnelSchlick(float cosTheta, vec3 F0) 22 | { 23 | return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); 24 | } 25 | 26 | void main(void) { 27 | 28 | vec3 offsets[6] = vec3[]( 29 | vec3( textureOffset, textureOffset, 0.0f), 30 | vec3( -textureOffset, -textureOffset, 0.0f), 31 | vec3(-textureOffset, 0.0f, textureOffset), 32 | vec3( textureOffset, 0.0f, -textureOffset), 33 | vec3( 0.0f, textureOffset, textureOffset), 34 | vec3( 0.0f, -textureOffset, -textureOffset) 35 | ); 36 | 37 | vec3 V = normalize(u_cameraPosition - v_position); 38 | vec3 N = normalize(v_normalVector); 39 | vec3 R = reflect(-V, N); 40 | vec3 specular = textureLod(u_skybox, R, u_roughness*10.0).rgb; 41 | 42 | float level = 13.0; 43 | vec3 irradiance = textureLod(u_skybox, R, level).rgb; 44 | for(int i = 0; i < 6; i++) 45 | { 46 | irradiance += vec3(textureLod(u_skybox, R + offsets[i], level)); 47 | } 48 | irradiance /= 7.0; 49 | 50 | vec3 F0 = vec3(0.04); 51 | F0 = mix(F0, u_albedo, u_metallic); 52 | vec3 fresnel = fresnelSchlick(dot(V,N), F0); 53 | 54 | vec3 kS = fresnel; 55 | vec3 kD = vec3(1.0) - kS; 56 | kD *= 1.0 - u_metallic; 57 | 58 | vec3 diffuse = irradiance * u_albedo; 59 | 60 | vec3 c = (kD * diffuse + specular*(kS+vec3(0.1))); 61 | 62 | FragColor = vec4(c, 1.0); 63 | //FragColor = vec4(vec3(kD), 1.0); 64 | } 65 | -------------------------------------------------------------------------------- /core/math/LineSegment.cpp: -------------------------------------------------------------------------------- 1 | #include "LineSegment.h" 2 | 3 | using namespace mgp; 4 | 5 | bool LineSegment::intersection(const LineSegment& that, Vector3* intersectPoint, bool strict) const { 6 | const Vector3& line1P1 = p1; 7 | const Vector3& line1P2 = p2; 8 | const Vector3& line2P1 = that.p1; 9 | const Vector3& line2P2 = that.p2; 10 | 11 | Vector3 v1 = line1P2 - line1P1; 12 | Vector3 v2 = line2P2 - line2P1; 13 | 14 | Vector3 startPointSeg = line2P1 - line1P1; 15 | Vector3 vecS1; Vector3::cross(v1, v2, &vecS1); 16 | Vector3 vecS2; Vector3::cross(startPointSeg, v2, &vecS2); 17 | 18 | double num = Vector3::dot(startPointSeg, vecS1); 19 | if (strict && (num >= 1E-05f || num <= -1E-05f)) 20 | { 21 | return false; 22 | } 23 | 24 | double lengthSquared = vecS1.lengthSquared(); 25 | if (lengthSquared < 1E-05f) { 26 | return false; 27 | } 28 | 29 | double num2 = Vector3::dot(vecS2, vecS1) / lengthSquared; 30 | if (num2 > 1 || num2 < 0) { 31 | return false; 32 | } 33 | 34 | *intersectPoint = line1P1 + v1 * num2; 35 | return true; 36 | } 37 | 38 | Float LineSegment::distanceToPoint(const Vector3& point) const { 39 | Vector3 v1 = p2 - p1; 40 | Vector3 v2 = point - p1; 41 | 42 | double dotP = Vector3::dot(v1, v2); 43 | if (dotP < 0) { 44 | return point.distance(p1); 45 | } 46 | if (dotP > v1.lengthSquared()) { 47 | return point.distance(p2); 48 | } 49 | 50 | Vector3 vecS1; Vector3::cross(v1, v2, &vecS1); 51 | return vecS1.length() / v1.length(); 52 | } 53 | 54 | bool mgp::triangleNormal(const Vector3& p1, const Vector3& p2, const Vector3& p3, Vector3* normal) { 55 | Vector3 d1 = p2 - p1; 56 | Vector3 d2 = p3 - p1; 57 | Vector3::cross(d1, d2, normal); 58 | return normal->normalize(normal); 59 | } -------------------------------------------------------------------------------- /core/objects/TextureAtlas.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef TEXTUREATLAS_H_ 9 | #define TEXTUREATLAS_H_ 10 | 11 | #include "material/Texture.h" 12 | #include "material/ShaderProgram.h" 13 | #include "scene/Mesh.h" 14 | #include "math/Rectangle.h" 15 | #include "math/Matrix.h" 16 | #include "material/Material.h" 17 | #include "scene/MeshBatch.h" 18 | 19 | namespace mgp 20 | { 21 | class SpriteBatch; 22 | 23 | class TextureAtlas : public Refable { 24 | Texture* texture; 25 | 26 | int lastX; 27 | int curY; 28 | int maxY; 29 | bool isFull; 30 | 31 | std::vector rects; 32 | unsigned char* data; 33 | 34 | public: 35 | TextureAtlas(Image::Format format, int w, int h); 36 | ~TextureAtlas(); 37 | 38 | bool addImageData(int imgW, int imgH, const unsigned char* imgData, Rectangle& rect); 39 | bool addImage(Image* image, Rectangle& rect); 40 | bool addImageUri(const std::string& file, Rectangle& rect); 41 | 42 | Texture* getTexture() { return texture; } 43 | private: 44 | template 45 | void copyImageData(unsigned char* dst, int dstW, int dstH, int x, int y, const unsigned char* src, int imgW, int imgH) { 46 | for (int i = 0; i < imgH; ++i) { 47 | int dstRow = (y + i) * dstW * pixelSize; 48 | int srcRow = i * imgW * pixelSize; 49 | for (int j = 0; j < imgW; ++j) { 50 | int dstX = (x + j) * pixelSize; 51 | int srcX = j * pixelSize; 52 | 53 | for (int k = 0; k < pixelSize; ++k) { 54 | dst[dstRow + dstX + k] = src[srcRow + srcX + k]; 55 | } 56 | } 57 | } 58 | } 59 | }; 60 | 61 | } 62 | 63 | #endif -------------------------------------------------------------------------------- /modules/ui/ProgressBar.h: -------------------------------------------------------------------------------- 1 | #ifndef PROGRESS_BAR_H_ 2 | #define PROGRESS_BAR_H_ 3 | 4 | #include "base/Base.h" 5 | #include "Theme.h" 6 | #include "base/Properties.h" 7 | #include "Button.h" 8 | 9 | namespace mgp 10 | { 11 | 12 | 13 | class ProgressBar : public Control 14 | { 15 | friend class Control; 16 | 17 | public: 18 | 19 | /** 20 | * Set this slider's value. The new value will be clamped to fit within 21 | * the slider's minimum and maximum values. 22 | * 23 | * @param value The new value. 24 | */ 25 | void setValue(float value, bool fireEvent = true); 26 | 27 | /** 28 | * Get this slider's current value. 29 | * 30 | * @return This slider's current value. 31 | */ 32 | float getValue() const; 33 | 34 | protected: 35 | 36 | /** 37 | * Constructor. 38 | */ 39 | ProgressBar(); 40 | 41 | /** 42 | * Destructor. 43 | */ 44 | ~ProgressBar(); 45 | 46 | 47 | virtual void onSerialize(Serializer* serializer); 48 | 49 | virtual void onDeserialize(Serializer* serializer); 50 | 51 | /** 52 | * @see Control::drawImages 53 | */ 54 | unsigned int drawImages(Form* form, const Rectangle& clip, RenderInfo* view); 55 | 56 | /** 57 | * @see Control::updateState 58 | */ 59 | void updateState(State state); 60 | 61 | /** 62 | * @see Control::updateBounds 63 | */ 64 | void measureSize(); 65 | 66 | /** 67 | * The Slider's current value. 68 | */ 69 | float _value; 70 | 71 | /** 72 | * The image for the slider track. 73 | */ 74 | ThemeImage* _trackImage; 75 | 76 | private: 77 | 78 | /** 79 | * Constructor. 80 | */ 81 | ProgressBar(const ProgressBar& copy) = delete; 82 | 83 | 84 | float _trackHeight; 85 | }; 86 | 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /core/base/ThreadPool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | 11 | #ifndef ThreadPool_hpp 12 | #define ThreadPool_hpp 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "Ref.h" 19 | #include "Queue.h" 20 | #include "Ptr.h" 21 | 22 | namespace mgp { 23 | 24 | 25 | class Task : public Refable { 26 | friend class ThreadPool; 27 | protected: 28 | bool _done; 29 | bool canceled; 30 | 31 | public: 32 | Task() 33 | : _done(false) , canceled(false) { 34 | } 35 | 36 | virtual ~Task() {} 37 | 38 | virtual void run() {} 39 | 40 | virtual void cancel() { canceled = true; } 41 | bool isCanceled() { return canceled; } 42 | bool isDone() { return _done; } 43 | 44 | virtual void done() { 45 | _done = true; 46 | } 47 | }; 48 | 49 | /** 50 | * Thread Pool 51 | */ 52 | class ThreadPool { 53 | public: 54 | typedef SPtr TaskPtr; 55 | 56 | protected: 57 | BlockingQueue queue; 58 | bool onlyRunLatest; 59 | 60 | private: 61 | std::vector threadList; 62 | int threadSize; 63 | 64 | public: 65 | ThreadPool(int threadSize); 66 | virtual ~ThreadPool(); 67 | 68 | bool start(); 69 | 70 | void stop(); 71 | 72 | void addTask(TaskPtr task); 73 | 74 | /** 75 | * cancel and remove the task 76 | */ 77 | void remove(Task *task); 78 | 79 | /** 80 | * call visit for each one task 81 | */ 82 | void each(); 83 | 84 | protected: 85 | virtual bool visit(Task *t, int index) { return true; } 86 | 87 | private: 88 | void run(); 89 | static int enterPoint(void *arg); 90 | }; 91 | 92 | } 93 | 94 | #endif /* ThreadPool_hpp */ 95 | -------------------------------------------------------------------------------- /res/shaders/terrain.vert: -------------------------------------------------------------------------------- 1 | 2 | #include "_lighting_def.glsl" 3 | 4 | 5 | /////////////////////////////////////////////////////////// 6 | // Uniforms 7 | uniform mat4 u_projectionMatrix; 8 | 9 | /////////////////////////////////////////////////////////// 10 | // Attributes 11 | in vec3 a_position; 12 | in vec2 a_texCoord0; 13 | 14 | /////////////////////////////////////////////////////////// 15 | // Varyings 16 | 17 | out vec2 v_texCoord0; 18 | #if LAYER_COUNT > 0 19 | out vec2 v_texCoordLayer0; 20 | #endif 21 | #if LAYER_COUNT > 1 22 | out vec2 v_texCoordLayer1; 23 | #endif 24 | #if LAYER_COUNT > 2 25 | out vec2 v_texCoordLayer2; 26 | #endif 27 | 28 | #if defined(SKINNING) 29 | #include "_skinning.vert" 30 | #else 31 | #include "_skinning-none.vert" 32 | #endif 33 | 34 | #if defined(LIGHTING) 35 | #include "_lighting.vert" 36 | #endif 37 | 38 | void main() 39 | { 40 | // Transform position to clip space. 41 | vec4 position = getPosition(); 42 | 43 | gl_Position = u_projectionMatrix * position; 44 | 45 | 46 | #if defined(LIGHTING) 47 | 48 | #if !defined(NORMAL_MAP) 49 | v_normalVector = normalize((u_inverseTransposeWorldViewMatrix * vec4(a_normal.x, a_normal.y, a_normal.z, 0)).xyz); 50 | #endif 51 | 52 | initLightDirection(position); 53 | 54 | #endif 55 | 56 | // Pass base texture coord 57 | v_texCoord0 = a_texCoord0; 58 | 59 | //flip Y 60 | v_texCoord0.y = 1.0 - v_texCoord0.y; 61 | 62 | // Pass repeated texture coordinates for each layer 63 | #if LAYER_COUNT > 0 64 | v_texCoordLayer0 = a_texCoord0 * TEXTURE_REPEAT_0; 65 | #endif 66 | #if LAYER_COUNT > 1 67 | v_texCoordLayer1 = a_texCoord0 * TEXTURE_REPEAT_1; 68 | #endif 69 | #if LAYER_COUNT > 2 70 | v_texCoordLayer2 = a_texCoord0 * TEXTURE_REPEAT_2; 71 | #endif 72 | } 73 | -------------------------------------------------------------------------------- /core/base/StringUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | #ifndef STRINGUTIL_H_ 11 | #define STRINGUTIL_H_ 12 | 13 | 14 | #include 15 | #include 16 | 17 | namespace mgp 18 | { 19 | 20 | class StringUtil { 21 | public: 22 | typedef std::string String; 23 | 24 | static size_t hashCode(const String& self); 25 | static bool iequals(const String& self, const String &other); 26 | static bool contains(const String& self, const String& s); 27 | static bool startsWith(const String& self, const String& s); 28 | static bool endsWith(const String& self, const String& s); 29 | 30 | static void replace(String& self, const String& src, const String& dst); 31 | static std::vector split(const String& self, const String &sep); 32 | static String substr(const String& self, size_t pos, size_t len = -1); 33 | 34 | static void trimEnd(String& self); 35 | static void trimStart(String& self); 36 | static void trim(String& self) { trimStart(self); trimEnd(self); } 37 | static void removeLastChar(String& self); 38 | 39 | static String toLower(const String& self); 40 | static String toUpper(const String& self); 41 | 42 | static int toInt(const String& self); 43 | static int64_t toLong(const String& self); 44 | static float toFloat(const String& self); 45 | static double toDouble(const String& self); 46 | 47 | static String fromInt(int i); 48 | static String fromLong(int64_t i); 49 | static String fromDouble(double f); 50 | static String fromFloat(float f); 51 | 52 | /** 53 | * 'printf' style format 54 | */ 55 | static String format(const char* fmt, ...); 56 | }; 57 | 58 | } 59 | 60 | #endif -------------------------------------------------------------------------------- /core/math/Vector3.inl: -------------------------------------------------------------------------------- 1 | #include "math/Vector3.h" 2 | #include "math/Matrix.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | inline const Vector3 Vector3::operator+(const Vector3& v) const 8 | { 9 | Vector3 result(*this); 10 | result.add(v); 11 | return result; 12 | } 13 | 14 | inline Vector3& Vector3::operator+=(const Vector3& v) 15 | { 16 | add(v); 17 | return *this; 18 | } 19 | 20 | inline const Vector3 Vector3::operator-(const Vector3& v) const 21 | { 22 | Vector3 result(*this); 23 | result.subtract(v); 24 | return result; 25 | } 26 | 27 | inline Vector3& Vector3::operator-=(const Vector3& v) 28 | { 29 | subtract(v); 30 | return *this; 31 | } 32 | 33 | inline const Vector3 Vector3::operator-() const 34 | { 35 | Vector3 result(*this); 36 | result.negate(); 37 | return result; 38 | } 39 | 40 | inline const Vector3 Vector3::operator*(Float x) const 41 | { 42 | Vector3 result(*this); 43 | result.scale(x); 44 | return result; 45 | } 46 | 47 | inline Vector3& Vector3::operator*=(Float x) 48 | { 49 | scale(x); 50 | return *this; 51 | } 52 | 53 | inline const Vector3 Vector3::operator/(const Float x) const 54 | { 55 | return Vector3(this->x / x, this->y / x, this->z / x); 56 | } 57 | 58 | inline bool Vector3::operator<(const Vector3& v) const 59 | { 60 | if (x == v.x) 61 | { 62 | if (y == v.y) 63 | { 64 | return z < v.z; 65 | } 66 | return y < v.y; 67 | } 68 | return x < v.x; 69 | } 70 | 71 | inline bool Vector3::operator==(const Vector3& v) const 72 | { 73 | return x==v.x && y==v.y && z==v.z; 74 | } 75 | 76 | inline bool Vector3::operator!=(const Vector3& v) const 77 | { 78 | return x!=v.x || y!=v.y || z!=v.z; 79 | } 80 | 81 | inline const Vector3 operator*(Float x, const Vector3& v) 82 | { 83 | Vector3 result(v); 84 | result.scale(x); 85 | return result; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /res/shaders/_skinning-none.vert: -------------------------------------------------------------------------------- 1 | #ifdef MORPH_TARGET_COUNT 2 | #include "_morph.vert" 3 | #endif 4 | 5 | #ifdef INSTANCED 6 | in mat4 a_instanceMatrix; 7 | #else 8 | uniform mat4 u_worldViewMatrix; 9 | #endif 10 | 11 | vec4 getPosition() 12 | { 13 | vec3 pos = a_position; 14 | #ifdef MORPH_TARGET_COUNT 15 | pos = getMorphPosition(pos); 16 | #endif 17 | 18 | #ifdef INSTANCED 19 | return a_instanceMatrix * vec4(pos, 1.0); 20 | #else 21 | return u_worldViewMatrix * vec4(pos, 1.0); 22 | #endif 23 | } 24 | 25 | #if defined(LIGHTING) 26 | #if !defined(NORMAL_MAP) 27 | in vec3 a_normal; 28 | #endif 29 | 30 | #if defined(BUMPED) 31 | in vec3 a_tangent; 32 | //in vec3 a_binormal; 33 | #endif 34 | 35 | 36 | vec3 getViewSpaceVector(vec3 normal) { 37 | // Transform the normal, tangent and binormals to view space. 38 | #ifdef INSTANCED 39 | mat4 it = transpose(inverse(a_instanceMatrix)); 40 | mat3 inverseTransposeWorldViewMatrix = mat3(it[0].xyz, it[1].xyz, it[2].xyz); 41 | #else 42 | mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz); 43 | #endif 44 | vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal); 45 | return normalVector; 46 | } 47 | 48 | vec3 getNormal() 49 | { 50 | #if defined(NORMAL_MAP) 51 | return vec3(0.0, 0.0, 0.0); 52 | #else 53 | return getViewSpaceVector(a_normal); 54 | #endif 55 | } 56 | 57 | #if defined(BUMPED) 58 | vec3 getTangent() 59 | { 60 | return getViewSpaceVector(a_tangent); 61 | } 62 | 63 | vec3 getBinormal() 64 | { 65 | return getViewSpaceVector(cross(a_tangent, a_normal)); 66 | } 67 | #endif 68 | 69 | #endif -------------------------------------------------------------------------------- /example/Qt/mgpview.h: -------------------------------------------------------------------------------- 1 | #ifndef MGPVIEW_H 2 | #define MGPVIEW_H 3 | 4 | #include "mgp.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | /** 16 | * The main game view to render scenes into viewport(s). 17 | */ 18 | class MgpView : public QOpenGLWidget, protected QOpenGLFunctions, public mgp::Application 19 | { 20 | Q_OBJECT 21 | public: 22 | 23 | /** 24 | * Constructor. 25 | * 26 | * @param parent The parent widget. 27 | */ 28 | explicit MgpView(QWidget* parent = nullptr); 29 | 30 | /** 31 | * Destructor. 32 | */ 33 | ~MgpView(); 34 | 35 | protected: 36 | void initializeGL() override; 37 | void paintGL() override; 38 | void resizeGL(int width, int height) override; 39 | 40 | void initialize() override; 41 | void finalize() override; 42 | 43 | protected: 44 | 45 | /** 46 | * @see QWidget::mousePressEvent 47 | */ 48 | void mousePressEvent(QMouseEvent* evt) override; 49 | 50 | /** 51 | * @see QWidget::mouseReleaseEvent 52 | */ 53 | void mouseReleaseEvent(QMouseEvent* evt) override; 54 | 55 | /** 56 | * @see QWidget::mouseMoveEvent 57 | */ 58 | void mouseMoveEvent(QMouseEvent* evt) override; 59 | 60 | /** 61 | * @see QWidget::mouseWheelEvent 62 | */ 63 | void wheelEvent(QWheelEvent* evt) override; 64 | 65 | /** 66 | * @see QWidget::keyPressEvent 67 | */ 68 | void keyPressEvent(QKeyEvent* evt) override; 69 | 70 | /** 71 | * @see QWidget::keyReleaseEvent 72 | */ 73 | void keyReleaseEvent(QKeyEvent* evt) override; 74 | 75 | /** 76 | * @see QWidget::closeEvent 77 | */ 78 | void closeEvent(QCloseEvent* evt) override; 79 | 80 | private: 81 | 82 | bool _mouseDown = false; 83 | }; 84 | 85 | 86 | 87 | #endif // MGPVIEW_H 88 | -------------------------------------------------------------------------------- /modules/ui/TreeView.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_VIEW_H_ 2 | #define TREE_VIEW_H_ 3 | 4 | #include "ScrollContainer.h" 5 | #include "Label.h" 6 | #include "Theme.h" 7 | #include "base/Properties.h" 8 | 9 | namespace mgp 10 | { 11 | 12 | class TreeView : public ScrollContainer, public Control::Listener { 13 | friend class Control; 14 | public: 15 | 16 | class TreeItem: public Refable { 17 | friend class TreeView; 18 | public: 19 | std::vector > children; 20 | std::string name; 21 | uint64_t id = 0; 22 | bool _isChecked = true; 23 | bool hasChildren = true; 24 | 25 | bool isChecked(); 26 | void setChecked(bool v); 27 | static SPtr create(uint64_t id, const char* name, const std::vector >& cs); 28 | bool expanded = false; 29 | void addChild(SPtr& c); 30 | TreeItem* getParent() { return _parent; } 31 | private: 32 | UPtr _contronl; 33 | TreeItem* _parent = NULL; 34 | }; 35 | 36 | SPtr root; 37 | 38 | std::function onItemCliked; 39 | protected: 40 | TreeItem* _selectItem = NULL; 41 | bool _isDirty = true; 42 | private: 43 | bool _useCheckBox = true; 44 | public: 45 | 46 | void setCheckbox(bool v); 47 | 48 | TreeItem* getSelectItem() { return _selectItem; } 49 | void setSelectItem(TreeItem* item); 50 | 51 | protected: 52 | TreeView(); 53 | ~TreeView(); 54 | 55 | virtual void onSerialize(Serializer* serializer); 56 | 57 | virtual void onDeserialize(Serializer* serializer); 58 | 59 | void update(float elapsedTime); 60 | 61 | void controlEvent(Control* control, EventType evt); 62 | 63 | virtual void checkedChange(TreeItem* item); 64 | private: 65 | void addItemLabel(TreeItem* item, int level); 66 | 67 | TreeItem* findTreeItem(Control* control, TreeItem* item); 68 | }; 69 | 70 | } 71 | 72 | 73 | #endif -------------------------------------------------------------------------------- /res/shaders/_lighting_def.glsl: -------------------------------------------------------------------------------- 1 | 2 | #ifndef DIRECTIONAL_LIGHT_COUNT 3 | #define DIRECTIONAL_LIGHT_COUNT 0 4 | #endif 5 | #ifndef SPOT_LIGHT_COUNT 6 | #define SPOT_LIGHT_COUNT 0 7 | #endif 8 | #ifndef POINT_LIGHT_COUNT 9 | #define POINT_LIGHT_COUNT 0 10 | #endif 11 | #if (DIRECTIONAL_LIGHT_COUNT > 0) || (POINT_LIGHT_COUNT > 0) || (SPOT_LIGHT_COUNT > 0) || defined(IBL) 12 | #define LIGHTING 13 | #endif 14 | #ifndef SHADOW_CASCADE_COUNT 15 | #define SHADOW_CASCADE_COUNT 2 16 | #endif 17 | 18 | #if defined(LIGHTING) 19 | 20 | #if defined(BUMPED) || defined(SIMPLE_BUMPED) 21 | uniform sampler2D u_normalmapTexture; 22 | #endif 23 | 24 | #ifndef INSTANCED 25 | uniform mat4 u_inverseTransposeWorldViewMatrix; 26 | #endif 27 | 28 | #if (DIRECTIONAL_LIGHT_COUNT > 0) 29 | uniform vec3 u_directionalLightColor[DIRECTIONAL_LIGHT_COUNT]; 30 | #if defined(SHADOW) 31 | uniform sampler2D u_directionalLightShadowMap[DIRECTIONAL_LIGHT_COUNT]; 32 | uniform mat4 u_directionalLightSpaceMatrix[DIRECTIONAL_LIGHT_COUNT*SHADOW_CASCADE_COUNT]; 33 | uniform float u_directionalLightCascadeDistance[DIRECTIONAL_LIGHT_COUNT*SHADOW_CASCADE_COUNT]; 34 | #endif 35 | uniform vec3 u_directionalLightDirection[DIRECTIONAL_LIGHT_COUNT]; 36 | #endif 37 | 38 | #if (POINT_LIGHT_COUNT > 0) 39 | uniform vec3 u_pointLightColor[POINT_LIGHT_COUNT]; 40 | uniform vec3 u_pointLightPosition[POINT_LIGHT_COUNT]; 41 | uniform float u_pointLightRangeInverse[POINT_LIGHT_COUNT]; 42 | #endif 43 | 44 | #if (SPOT_LIGHT_COUNT > 0) 45 | uniform vec3 u_spotLightColor[SPOT_LIGHT_COUNT]; 46 | uniform float u_spotLightRangeInverse[SPOT_LIGHT_COUNT]; 47 | uniform float u_spotLightInnerAngleCos[SPOT_LIGHT_COUNT]; 48 | uniform float u_spotLightOuterAngleCos[SPOT_LIGHT_COUNT]; 49 | uniform vec3 u_spotLightDirection[SPOT_LIGHT_COUNT]; 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /core/math/Vector4.inl: -------------------------------------------------------------------------------- 1 | #include "math/Matrix.h" 2 | #include "math/Vector4.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | inline const Vector4 Vector4::operator+(const Vector4& v) const 8 | { 9 | Vector4 result(*this); 10 | result.add(v); 11 | return result; 12 | } 13 | 14 | inline Vector4& Vector4::operator+=(const Vector4& v) 15 | { 16 | add(v); 17 | return *this; 18 | } 19 | 20 | inline const Vector4 Vector4::operator-(const Vector4& v) const 21 | { 22 | Vector4 result(*this); 23 | result.subtract(v); 24 | return result; 25 | } 26 | 27 | inline Vector4& Vector4::operator-=(const Vector4& v) 28 | { 29 | subtract(v); 30 | return *this; 31 | } 32 | 33 | inline const Vector4 Vector4::operator-() const 34 | { 35 | Vector4 result(*this); 36 | result.negate(); 37 | return result; 38 | } 39 | 40 | inline const Vector4 Vector4::operator*(Float x) const 41 | { 42 | Vector4 result(*this); 43 | result.scale(x); 44 | return result; 45 | } 46 | 47 | inline Vector4& Vector4::operator*=(Float x) 48 | { 49 | scale(x); 50 | return *this; 51 | } 52 | 53 | inline const Vector4 Vector4::operator/(const Float x) const 54 | { 55 | return Vector4(this->x / x, this->y / x, this->z / x, this->w / x); 56 | } 57 | 58 | inline bool Vector4::operator<(const Vector4& v) const 59 | { 60 | if (x == v.x) 61 | { 62 | if (y == v.y) 63 | { 64 | if (z == v.z) 65 | { 66 | return w < v.w; 67 | } 68 | return z < v.z; 69 | } 70 | return y < v.y; 71 | } 72 | return x < v.x; 73 | } 74 | 75 | inline bool Vector4::operator==(const Vector4& v) const 76 | { 77 | return x==v.x && y==v.y && z==v.z && w==v.w; 78 | } 79 | 80 | inline bool Vector4::operator!=(const Vector4& v) const 81 | { 82 | return x!=v.x || y!=v.y || z!=v.z || w!=v.w; 83 | } 84 | 85 | inline const Vector4 operator*(Float x, const Vector4& v) 86 | { 87 | Vector4 result(v); 88 | result.scale(x); 89 | return result; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /modules/mgp.h: -------------------------------------------------------------------------------- 1 | 2 | #include "mgp_core.h" 3 | 4 | // APP 5 | #include "app/Platform.h" 6 | #include "app/Application.h" 7 | //#include "app/ScreenDisplayer.h" 8 | #include "app/FirstPersonCamera.h" 9 | #include "app/SceneView.h" 10 | 11 | // Physics 12 | #include "physics/PhysicsController.h" 13 | #include "physics/PhysicsConstraint.h" 14 | #include "physics/PhysicsCollisionObject.h" 15 | #include "physics/PhysicsCollisionShape.h" 16 | #include "physics/PhysicsRigidBody.h" 17 | #include "physics/PhysicsGhostObject.h" 18 | #include "physics/PhysicsCharacter.h" 19 | #include "physics/PhysicsVehicle.h" 20 | #include "physics/PhysicsVehicleWheel.h" 21 | 22 | #ifndef __EMSCRIPTEN__ 23 | // Audio 24 | #include "audio/AudioController.h" 25 | #include "scene/AudioListener.h" 26 | #include "audio/AudioSource.h" 27 | 28 | // AI 29 | #include "ai/AIController.h" 30 | #include "ai/AIAgent.h" 31 | #include "ai/AIState.h" 32 | #include "ai/AIStateMachine.h" 33 | #endif 34 | 35 | // UI 36 | #ifdef GP_UI 37 | #include "ui/Theme.h" 38 | #include "ui/Control.h" 39 | //#include "ui/ControlFactory.h" 40 | #include "ui/Container.h" 41 | #include "ui/Form.h" 42 | #include "ui/Label.h" 43 | #include "ui/Button.h" 44 | #include "ui/CheckBox.h" 45 | #include "ui/TextBox.h" 46 | #include "ui/RadioButton.h" 47 | #include "ui/Slider.h" 48 | #include "ui/ImageView.h" 49 | #include "ui/JoystickControl.h" 50 | #include "ui/Layout.h" 51 | #include "ui/AbsoluteLayout.h" 52 | #include "ui/VerticalLayout.h" 53 | #include "ui/FlowLayout.h" 54 | #include "ui/ComboBox.h" 55 | #include "ui/TreeView.h" 56 | #include "ui/ScrollContainer.h" 57 | #include "ui/MenuList.h" 58 | #include "ui/FormManager.h" 59 | #include "ui/Icon.h" 60 | #include "ui/ProgressBar.h" 61 | #endif 62 | 63 | // Render 64 | #include "loader/GltfLoader.h" 65 | #include "render/RenderStage.h" 66 | #include "render/FrameBuffer.h" 67 | #include "openGL/GLFrameBuffer.h" 68 | #include "render/RenderPath.h" 69 | #include "openGL/DepthStencilTarget.h" 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /core/base/FileStream.h: -------------------------------------------------------------------------------- 1 | #ifndef FILESTREAM_H_ 2 | #define FILESTREAM_H_ 3 | 4 | #include "Stream.h" 5 | #include 6 | #include "Ptr.h" 7 | 8 | namespace mgp 9 | { 10 | 11 | /** 12 | * 13 | * @script{ignore} 14 | */ 15 | class FileStream : public Stream 16 | { 17 | public: 18 | friend class FileSystem; 19 | 20 | ~FileStream(); 21 | virtual bool canRead(); 22 | virtual bool canWrite(); 23 | virtual bool canSeek(); 24 | virtual void close(); 25 | virtual size_t read(void* ptr, size_t size, size_t count); 26 | virtual char* readLine(char* str, int num); 27 | virtual size_t write(const void* ptr, size_t size, size_t count); 28 | virtual bool eof(); 29 | virtual size_t length(); 30 | virtual long int position(); 31 | virtual bool seek(long int offset, int origin = SEEK_SET); 32 | virtual bool rewind(); 33 | 34 | static OwnPtr create(const char* filePath, const char* mode); 35 | 36 | private: 37 | FileStream(FILE* file); 38 | 39 | private: 40 | FILE* _file; 41 | bool _canRead; 42 | bool _canWrite; 43 | }; 44 | 45 | #ifdef __ANDROID__ 46 | 47 | class AAsset; 48 | /** 49 | * 50 | * @script{ignore} 51 | */ 52 | class FileStreamAndroid : public Stream 53 | { 54 | public: 55 | friend class FileSystem; 56 | 57 | ~FileStreamAndroid(); 58 | virtual bool canRead(); 59 | virtual bool canWrite(); 60 | virtual bool canSeek(); 61 | virtual void close(); 62 | virtual size_t read(void* ptr, size_t size, size_t count); 63 | virtual char* readLine(char* str, int num); 64 | virtual size_t write(const void* ptr, size_t size, size_t count); 65 | virtual bool eof(); 66 | virtual size_t length(); 67 | virtual long int position(); 68 | virtual bool seek(long int offset, int origin); 69 | virtual bool rewind(); 70 | 71 | static FileStreamAndroid* create(const char* filePath, const char* mode); 72 | 73 | private: 74 | FileStreamAndroid(AAsset* asset); 75 | 76 | private: 77 | AAsset* _asset; 78 | }; 79 | 80 | #endif 81 | 82 | } 83 | 84 | #endif -------------------------------------------------------------------------------- /doc/serializer.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 序列化 4 | 5 | ### 保存 6 | ``` 7 | auto sceneWriter = mgp::SerializerJson::createWriter("test.json"); 8 | sceneWriter->writeObject(nullptr, form->getContent()); 9 | sceneWriter->close(); 10 | ``` 11 | 12 | ### 加载 13 | ``` 14 | auto reader = mgp::Serializer::createReader("test.json"); 15 | auto content = reader->readObject(nullptr).dynamicCastTo(); 16 | ``` 17 | 18 | ### HiML格式 19 | ``` 20 | auto sceneWriter = mgp::SerializerJson::createWriter("ui.hml", true); 21 | sceneWriter->writeObject(nullptr, form->getContent()); 22 | 23 | auto reader = mgp::Serializer::createReader("ui.hml", true); 24 | auto content = reader->readObject(nullptr).dynamicCastTo(); 25 | ``` 26 | 27 | ## 自定义序列化对象 28 | ### 继承Serializable 29 | 需要重写的方法: 30 | ``` 31 | /** 32 | * Gets the class name string for the object. 33 | * 34 | * This is used by the Serializer when reading/writing objects. 35 | * The class name should be namespaced. Ex: mgp::SceneObject 36 | */ 37 | virtual std::string getClassName() override; 38 | 39 | /** 40 | * Event handled when an object is asked to serialize itself. 41 | * 42 | * @param serializer The serializer to write properties to. 43 | */ 44 | virtual void onSerialize(Serializer* serializer) override; 45 | 46 | /** 47 | * Event handled when an object properties are being deserialized. 48 | * 49 | * @param serializer The serializer to read properties from. 50 | */ 51 | virtual void onDeserialize(Serializer* serializer) override; 52 | 53 | ``` 54 | 55 | ### 注册函数 56 | 需要注册的方法: 57 | ``` 58 | static Serializable *createObject(); 59 | 60 | static std::string enumToString(const std::string& enumName, int value); 61 | 62 | static int enumParse(const std::string& enumName, const std::string& str); 63 | ``` 64 | 在启动时注册给SerializerManager(Application类中) 65 | ``` 66 | mgr->registerType("mgp::Camera", Camera::createObject); 67 | mgr->registerEnum("mgp::Camera::Mode", Camera::enumToString, Camera::enumParse); 68 | ``` 69 | -------------------------------------------------------------------------------- /modules/ui/Layout.h: -------------------------------------------------------------------------------- 1 | #ifndef LAYOUT_H_ 2 | #define LAYOUT_H_ 3 | 4 | #include "base/Ref.h" 5 | #include "platform/Mouse.h" 6 | #include "math/Vector2.h" 7 | 8 | namespace mgp 9 | { 10 | 11 | class Container; 12 | class Control; 13 | 14 | /** 15 | * Defines the layout for containers. 16 | * 17 | * Implementations are responsible for positioning, resizing and 18 | * calling update on all the controls within a container. 19 | * 20 | * @see http://gameplay3d.github.io/GamePlay/docs/file-formats.html#wiki-UI_Forms 21 | */ 22 | class Layout : public Refable 23 | { 24 | //friend class Container; 25 | 26 | public: 27 | 28 | /** 29 | * Layout types available to containers. 30 | */ 31 | enum Type 32 | { 33 | /** 34 | * Flow layout: Controls are placed next to one another horizontally 35 | * until the right-most edge of the container is reached, at which point 36 | * a new row is started. 37 | */ 38 | LAYOUT_FLOW, 39 | 40 | /** 41 | * Vertical layout: Controls are placed next to one another vertically until 42 | * the bottom-most edge of the container is reached. 43 | */ 44 | LAYOUT_VERTICAL, 45 | 46 | /** 47 | * Absolute layout: Controls are not modified at all by this layout. 48 | * They must be positioned and sized manually. 49 | */ 50 | LAYOUT_ABSOLUTE, 51 | 52 | /** 53 | * Horizontal layout 54 | */ 55 | LAYOUT_HORIZONTAL, 56 | }; 57 | 58 | /** 59 | * Get the type of this layout. 60 | * 61 | * @return The type of this layout. 62 | */ 63 | virtual Type getType() = 0; 64 | 65 | /** 66 | * Position, resize, and update the controls within a container. 67 | * 68 | * @param container The container to update. 69 | */ 70 | virtual void update(const Container* container) = 0; 71 | 72 | 73 | virtual float prefContentWidth(const Container* container); 74 | virtual float prefContentHeight(const Container* container); 75 | }; 76 | 77 | } 78 | 79 | #endif -------------------------------------------------------------------------------- /modules/ui/FormManager.h: -------------------------------------------------------------------------------- 1 | #ifndef FORM_MANAGER_H_ 2 | #define FORM_MANAGER_H_ 3 | 4 | #include "Form.h" 5 | 6 | namespace mgp 7 | { 8 | class SerializerManager; 9 | 10 | class FormManager { 11 | std::vector __forms; 12 | Form* _focusForm = NULL; 13 | friend class Control; 14 | friend class Form; 15 | private: 16 | /** 17 | * Get a form from its ID. 18 | * 19 | * @param id The ID of the form to search for. 20 | * 21 | * @return A form with the given ID, or null if one was not found. 22 | */ 23 | //static Form* getForm(const char* id); 24 | 25 | public: 26 | FormManager(); 27 | ~FormManager(); 28 | static FormManager* cur(); 29 | 30 | std::vector& getForms() { return __forms; } 31 | 32 | void add(UPtr
f); 33 | 34 | void remove(Form* form); 35 | 36 | void finalize(); 37 | 38 | /** 39 | * Draws this form. 40 | * 41 | * @return The nubmer of draw calls issued to draw the form. 42 | */ 43 | unsigned int draw(RenderInfo* view); 44 | 45 | /** 46 | * Updates all visible, enabled forms. 47 | */ 48 | void updateInternal(float elapsedTime); 49 | 50 | /** 51 | * Propagate key events to enabled forms. 52 | * 53 | * @return Whether the key event was consumed by a form. 54 | */ 55 | bool keyEventInternal(Keyboard::KeyEvent evt, int key); 56 | 57 | /** 58 | * Propagate mouse events to enabled forms. 59 | * 60 | * @return True if the mouse event is consumed or false if it is not consumed. 61 | * 62 | * @see MotionEvent::MotionType 63 | */ 64 | bool mouseEventInternal(MotionEvent& evt); 65 | 66 | /** 67 | * Fired by the platform when the game window resizes. 68 | * 69 | * @param width The new window width. 70 | * @param height The new window height. 71 | */ 72 | void resizeEventInternal(unsigned int width, unsigned int height); 73 | 74 | 75 | void verifyRemovedControlState(Control* control); 76 | 77 | static void regiseterSerializer(SerializerManager *mgr); 78 | }; 79 | 80 | } 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /modules/ui/HorizontalLayout.h: -------------------------------------------------------------------------------- 1 | #ifndef HORIZONTAL_LAYOUT_H_ 2 | #define HORIZONTAL_LAYOUT_H_ 3 | 4 | #include "Layout.h" 5 | #include "Container.h" 6 | 7 | namespace mgp 8 | { 9 | 10 | /** 11 | * Defines a vertical layout. 12 | * 13 | * Controls are placed next to one another vertically until 14 | * the bottom-most edge of the container is reached. 15 | */ 16 | class HorizontalLayout : public Layout 17 | { 18 | //friend class Form; 19 | //friend class Container; 20 | 21 | public: 22 | 23 | /** 24 | * Get the type of this Layout. 25 | * 26 | * @return Layout::LAYOUT_VERTICAL 27 | */ 28 | Layout::Type getType(); 29 | 30 | /** 31 | * Returns the vertical spacing between controls in the layout. 32 | * 33 | * @return The vertical spacing between controls. 34 | */ 35 | int getSpacing() const; 36 | 37 | /** 38 | * Sets the vertical spacing to add between controls in the layout. 39 | * 40 | * @param spacing The vertical spacing between controls. 41 | */ 42 | void setSpacing(int spacing); 43 | 44 | /** 45 | * Create a HorizontalLayout. 46 | * 47 | * @return a HorizontalLayout object. 48 | */ 49 | static UPtr create(); 50 | protected: 51 | 52 | /** 53 | * Constructor. 54 | */ 55 | HorizontalLayout(); 56 | 57 | /** 58 | * Destructor. 59 | */ 60 | virtual ~HorizontalLayout(); 61 | 62 | /** 63 | * Update the controls contained by the specified container. 64 | * 65 | * Controls are placed next to one another vertically until 66 | * the bottom-most edge of the container is reached. 67 | * 68 | * @param container The container to update. 69 | */ 70 | void update(const Container* container) override; 71 | 72 | float prefContentWidth(const Container* container) override; 73 | 74 | /** 75 | * Spacing between controls in the layout. 76 | */ 77 | int _spacing; 78 | 79 | private: 80 | 81 | /** 82 | * Constructor. 83 | */ 84 | HorizontalLayout(const HorizontalLayout& copy); 85 | 86 | 87 | }; 88 | 89 | } 90 | 91 | #endif -------------------------------------------------------------------------------- /core/mgp_core.h: -------------------------------------------------------------------------------- 1 | // Core 2 | #include "base/Base.h" 3 | #include "platform/Toolkit.h" 4 | #include "platform/Keyboard.h" 5 | #include "platform/Mouse.h" 6 | 7 | #include "base/FileSystem.h" 8 | #include "math/MathUtil.h" 9 | #include "base/Logger.h" 10 | #include "base/SerializerManager.h" 11 | #include "base/SerializerJson.h" 12 | #include "base/SerializerBinary.h" 13 | #include "base/Serializable.h" 14 | #include "base/Cache.h" 15 | #include "base/ThreadPool.h" 16 | #include "base/StringUtil.h" 17 | #include "base/System.h" 18 | #include "base/Buffer.h" 19 | #include "base/Ptr.h" 20 | #include "base/Ref.h" 21 | 22 | // Math 23 | #include "math/Rectangle.h" 24 | #include "math/Vector2.h" 25 | #include "math/Vector3.h" 26 | #include "math/Vector4.h" 27 | #include "math/Quaternion.h" 28 | #include "math/Matrix.h" 29 | #include "scene/Transform.h" 30 | #include "math/Ray.h" 31 | #include "math/Plane.h" 32 | #include "math/Frustum.h" 33 | #include "math/BoundingSphere.h" 34 | #include "math/BoundingBox.h" 35 | #include "math/Curve.h" 36 | 37 | // Graphics 38 | #include "material/Image.h" 39 | #include "material/Texture.h" 40 | #include "scene/Mesh.h" 41 | #include "scene/MeshFactory.h" 42 | #include "material/ShaderProgram.h" 43 | #include "material/Material.h" 44 | #include "scene/VertexFormat.h" 45 | #include "material/VertexAttributeBinding.h" 46 | #include "scene/Drawable.h" 47 | #include "scene/Model.h" 48 | #include "scene/Camera.h" 49 | #include "scene/Light.h" 50 | #include "scene/Node.h" 51 | #include "scene/Scene.h" 52 | #include "objects/Font.h" 53 | #include "objects/SpriteBatch.h" 54 | #include "objects/Sprite.h" 55 | // #include "objects/Text.h" 56 | #include "objects/TileSet.h" 57 | 58 | //#include "platform/ScreenDisplayer.h" 59 | #include "objects/HeightField.h" 60 | #include "objects/Terrain.h" 61 | #include "objects/TerrainPatch.h" 62 | #include "scene/AssetManager.h" 63 | 64 | // #include "objects/BillboardSet.h" 65 | 66 | #include "objects/TextureAtlas.h" 67 | 68 | // Animation 69 | #include "animation/AnimationController.h" 70 | #include "animation/AnimationTarget.h" 71 | #include "animation/AnimationValue.h" 72 | #include "animation/Animation.h" 73 | #include "animation/AnimationClip.h" 74 | -------------------------------------------------------------------------------- /modules/ai/AIState.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "AIState.h" 3 | #include "AIAgent.h" 4 | #include "AIStateMachine.h" 5 | #include "scene/Node.h" 6 | 7 | namespace mgp 8 | { 9 | 10 | AIState* AIState::_empty = NULL; 11 | 12 | AIState::AIState(const char* id) 13 | : _id(id), _listener(NULL) 14 | { 15 | } 16 | 17 | AIState::~AIState() 18 | { 19 | } 20 | 21 | UPtr AIState::create(const char* id) 22 | { 23 | return UPtr(new AIState(id)); 24 | } 25 | 26 | const char* AIState::getId() const 27 | { 28 | return _id.c_str(); 29 | } 30 | 31 | void AIState::setListener(Listener* listener) 32 | { 33 | _listener = listener; 34 | } 35 | 36 | void AIState::enter(AIStateMachine* stateMachine) 37 | { 38 | if (_listener) 39 | _listener->stateEnter(stateMachine->getAgent(), this); 40 | 41 | #ifdef GP_SCRIPT_ENABLE 42 | Node* node = stateMachine->_agent->_node; 43 | if (node) 44 | node->fireScriptEvent(GP_GET_SCRIPT_EVENT(Node, stateEnter), dynamic_cast(node), this); 45 | #endif // GP_SCRIPT_ENABLE 46 | } 47 | 48 | void AIState::exit(AIStateMachine* stateMachine) 49 | { 50 | if (_listener) 51 | _listener->stateExit(stateMachine->getAgent(), this); 52 | #ifdef GP_SCRIPT_ENABLE 53 | Node* node = stateMachine->_agent->_node; 54 | if (node) 55 | node->fireScriptEvent(GP_GET_SCRIPT_EVENT(Node, stateExit), dynamic_cast(node), this); 56 | #endif 57 | } 58 | 59 | void AIState::update(AIStateMachine* stateMachine, float elapsedTime) 60 | { 61 | if (_listener) 62 | _listener->stateUpdate(stateMachine->getAgent(), this, elapsedTime); 63 | #ifdef GP_SCRIPT_ENABLE 64 | Node* node = stateMachine->_agent->_node; 65 | if (node) 66 | node->fireScriptEvent(GP_GET_SCRIPT_EVENT(Node, stateUpdate), dynamic_cast(node), this, elapsedTime); 67 | #endif 68 | } 69 | 70 | AIState::Listener::~Listener() 71 | { 72 | } 73 | 74 | void AIState::Listener::stateEnter(AIAgent* agent, AIState* state) 75 | { 76 | } 77 | 78 | void AIState::Listener::stateExit(AIAgent* agent, AIState* state) 79 | { 80 | } 81 | 82 | void AIState::Listener::stateUpdate(AIAgent* agent, AIState* state, float elapsedTime) 83 | { 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /core/animation/AnimationValue.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "AnimationValue.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | AnimationValue::AnimationValue(unsigned int componentCount) 8 | : _componentCount(componentCount), _componentSize(componentCount * sizeof(Float)) 9 | { 10 | GP_ASSERT(_componentCount > 0); 11 | _value = new Float[_componentCount]; 12 | } 13 | 14 | AnimationValue::AnimationValue(const AnimationValue& copy) 15 | { 16 | _value = new Float[copy._componentCount]; 17 | _componentSize = copy._componentSize; 18 | _componentCount = copy._componentCount; 19 | memcpy(_value, copy._value, _componentSize); 20 | } 21 | 22 | AnimationValue::~AnimationValue() 23 | { 24 | SAFE_DELETE_ARRAY(_value); 25 | } 26 | 27 | AnimationValue& AnimationValue::operator=(const AnimationValue& v) 28 | { 29 | if (this != &v) 30 | { 31 | if (_value == NULL || _componentSize != v._componentSize || _componentCount != v._componentCount) 32 | { 33 | _componentSize = v._componentSize; 34 | _componentCount = v._componentCount; 35 | SAFE_DELETE_ARRAY(_value); 36 | _value = new Float[v._componentCount]; 37 | } 38 | memcpy(_value, v._value, _componentSize); 39 | } 40 | return *this; 41 | } 42 | 43 | Float AnimationValue::getFloat(unsigned int index) const 44 | { 45 | GP_ASSERT(index < _componentCount); 46 | GP_ASSERT(_value); 47 | 48 | return _value[index]; 49 | } 50 | 51 | void AnimationValue::setFloat(unsigned int index, Float value) 52 | { 53 | GP_ASSERT(index < _componentCount); 54 | GP_ASSERT(_value); 55 | 56 | _value[index] = value; 57 | } 58 | 59 | void AnimationValue::getFloats(unsigned int index, Float* values, unsigned int count) const 60 | { 61 | GP_ASSERT(_value && values && index < _componentCount && (index + count) <= _componentCount); 62 | 63 | memcpy(values, &_value[index], count * sizeof(Float)); 64 | } 65 | 66 | void AnimationValue::setFloats(unsigned int index, Float* values, unsigned int count) 67 | { 68 | GP_ASSERT(_value && values && index < _componentCount && (index + count) <= _componentCount); 69 | 70 | memcpy(&_value[index], values, count * sizeof(Float)); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /core/platform/Mouse.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef MOUSE_H_ 9 | #define MOUSE_H_ 10 | 11 | #include "base/Base.h" 12 | 13 | namespace mgp 14 | { 15 | 16 | class MotionEvent { 17 | public: 18 | enum MotionType { 19 | press, 20 | release, 21 | touchMove, 22 | mouseMove, 23 | longPress, 24 | click, 25 | cancel, 26 | wheel, 27 | other, 28 | }; 29 | 30 | enum Button { 31 | left, 32 | middle, 33 | right, 34 | }; 35 | 36 | /** 37 | * Maximum simultaneous touch points supported. 38 | */ 39 | static const unsigned int MAX_TOUCH_POINTS = 10; 40 | 41 | /** 42 | * event occurs time 43 | */ 44 | int64_t time; 45 | 46 | /** 47 | * event type 48 | */ 49 | MotionType type; 50 | 51 | /** 52 | * The order of occurrence for multiple touch contacts starting at zero. 53 | */ 54 | int contactIndex; 55 | 56 | /** 57 | ** X coordinates 58 | **/ 59 | int x; 60 | 61 | /** 62 | ** Y coordinates 63 | **/ 64 | int y; 65 | 66 | /** 67 | ** Delta value of event. For mouse wheel events this is the 68 | ** amount the mouse wheel has traveled. 69 | **/ 70 | int wheelDelta; 71 | 72 | /** 73 | ** Number of mouse clicks. 74 | **/ 75 | int count; 76 | 77 | /** 78 | ** Mouse button number pressed 79 | **/ 80 | Button button; 81 | 82 | /** 83 | ** Current pressure of pointer 84 | **/ 85 | double pressure; 86 | 87 | /** 88 | ** Current size of pointer 89 | **/ 90 | double size; 91 | 92 | /** 93 | ** native event 94 | **/ 95 | void *rawEvent; 96 | 97 | /** 98 | ** For muilt touch event 99 | **/ 100 | std::vector pointers; 101 | 102 | public: 103 | MotionEvent() : contactIndex(0), time(0), 104 | type(other), 105 | wheelDelta(0), 106 | count(0), 107 | button(left), 108 | pressure(0), 109 | size(0), 110 | rawEvent(NULL) 111 | { 112 | } 113 | }; 114 | 115 | 116 | typedef MotionEvent& Mouse; 117 | 118 | 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /modules/ui/HorizontalLayout.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "HorizontalLayout.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | HorizontalLayout::HorizontalLayout() : _spacing(0) 8 | { 9 | } 10 | 11 | HorizontalLayout::~HorizontalLayout() 12 | { 13 | } 14 | 15 | UPtr HorizontalLayout::create() 16 | { 17 | return UPtr(new HorizontalLayout()); 18 | } 19 | 20 | Layout::Type HorizontalLayout::getType() 21 | { 22 | return Layout::LAYOUT_HORIZONTAL; 23 | } 24 | 25 | int HorizontalLayout::getSpacing() const 26 | { 27 | return _spacing; 28 | } 29 | 30 | void HorizontalLayout::setSpacing(int spacing) 31 | { 32 | _spacing = spacing; 33 | } 34 | 35 | void HorizontalLayout::update(const Container* container) 36 | { 37 | GP_ASSERT(container); 38 | 39 | // Need border, padding. 40 | //Border border = container->getBorder(container->getState()); 41 | //Padding padding = container->getPadding(); 42 | 43 | float xPosition = 0; 44 | 45 | const std::vector& controls = container->getControls(); 46 | 47 | int i, end, iter; 48 | i = 0; 49 | end = (int)controls.size(); 50 | iter = 1; 51 | 52 | while (i != end) 53 | { 54 | Control* control = controls.at(i); 55 | GP_ASSERT(control); 56 | 57 | if (control->isVisible()) 58 | { 59 | const Rectangle& bounds = control->getBounds(); 60 | const Margin& margin = control->getMargin(); 61 | 62 | xPosition += margin.left; 63 | 64 | control->setXInternal(xPosition); 65 | 66 | xPosition += bounds.width + margin.right + _spacing; 67 | } 68 | 69 | i += iter; 70 | } 71 | } 72 | 73 | float HorizontalLayout::prefContentWidth(const Container* container) { 74 | // Size ourself to tightly fit the height of our children 75 | float width = 0; 76 | for (size_t i = 0, count = container->getControls().size(); i < count; ++i) 77 | { 78 | Control* ctrl = container->getControls()[i]; 79 | if (ctrl->isVisible() && !ctrl->isWidthPercentage()) 80 | { 81 | float h = ctrl->getMeasureBufferedWidth(); 82 | 83 | width += h + _spacing; 84 | } 85 | } 86 | return width; 87 | } 88 | 89 | } -------------------------------------------------------------------------------- /modules/render/RenderDataManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef RENDE_DATA_MANAGER_H 9 | #define RENDE_DATA_MANAGER_H 10 | 11 | #include "scene/Renderer.h" 12 | #include "scene/Scene.h" 13 | #include "scene/Camera.h" 14 | 15 | #include "objects/Instanced.h" 16 | 17 | namespace mgp 18 | { 19 | 20 | class RenderData { 21 | public: 22 | std::vector _drawList; 23 | 24 | std::vector* lights = NULL; 25 | Camera* camera = NULL; 26 | Rectangle viewport; 27 | 28 | Material* _overridedMaterial = NULL; 29 | int _overridedDepthState = 0; 30 | 31 | bool wireframe = false; 32 | bool isDepthPass = false; 33 | }; 34 | 35 | class RenderDataManager { 36 | bool _viewFrustumCulling; 37 | bool _useInstanced; 38 | Camera *_camera = NULL; 39 | 40 | struct InstanceKey { 41 | void* mesh; 42 | void* material; 43 | bool operator<(const InstanceKey& b) const { 44 | if (this->mesh != b.mesh) { 45 | return this->mesh < b.mesh; 46 | } 47 | return material < b.material; 48 | } 49 | }; 50 | 51 | std::map > _groupByInstance; 52 | std::vector _orderedInstance; 53 | std::map > _instanceds; 54 | RenderInfo _renderInfo; 55 | 56 | public: 57 | std::map > _renderQueues; 58 | std::vector _lights; 59 | 60 | RenderDataManager(); 61 | 62 | void fill(Scene* scene, Camera *camera, Rectangle *viewport, bool viewFrustumCulling = true); 63 | void fillDrawables(std::vector& drawables, Camera *camera, Rectangle *viewport, bool viewFrustumCulling = true); 64 | void sort(); 65 | void getRenderData(RenderData* view, int layer); 66 | protected: 67 | bool buildRenderQueues(Node* node); 68 | void addInstanced(DrawCall* drawCall); 69 | void setInstanced(Instanced* instance_, std::vector& list); 70 | void addToQueue(DrawCall* drawCall); 71 | void filterInstanced(); 72 | void clear(); 73 | void endFill(); 74 | }; 75 | } 76 | 77 | #endif -------------------------------------------------------------------------------- /modules/ui/Icon.h: -------------------------------------------------------------------------------- 1 | #ifndef ICON_H_ 2 | #define ICON_H_ 3 | 4 | #include "Control.h" 5 | #include "Theme.h" 6 | #include "material/Image.h" 7 | #include "objects/SpriteBatch.h" 8 | #include "math/Rectangle.h" 9 | 10 | namespace mgp 11 | { 12 | 13 | /** 14 | * Defines an image control. 15 | * 16 | * This allows forms to display seperate images from arbitrary files not specified in the theme. 17 | * 18 | * @see http://gameplay3d.github.io/GamePlay/docs/file-formats.html#wiki-UI_Forms 19 | */ 20 | class Icon : public Control 21 | { 22 | friend class Control; 23 | 24 | bool _checked = false; 25 | bool _checkable = false; 26 | public: 27 | 28 | /** 29 | * Set the path of the image for this ImageControl to display. 30 | * 31 | * @param path The path to the image. 32 | */ 33 | void setImagePath(const char* path); 34 | 35 | const char* getImagePath(); 36 | 37 | bool isCheckable() { return _checkable; } 38 | void setCheckable(bool c) { _checkable = c; } 39 | 40 | /** 41 | * Gets whether this checkbox is checked. 42 | * 43 | * @return Whether this checkbox is checked. 44 | */ 45 | bool isChecked(); 46 | 47 | /** 48 | * Sets whether the checkbox is checked. 49 | * 50 | * @param checked TRUE if the checkbox is checked; FALSE if the checkbox is not checked. 51 | */ 52 | void setChecked(bool checked); 53 | 54 | protected: 55 | 56 | Icon(); 57 | 58 | virtual ~Icon(); 59 | 60 | virtual void onSerialize(Serializer* serializer); 61 | 62 | virtual void onDeserialize(Serializer* serializer); 63 | 64 | virtual unsigned int drawImages(Form* form, const Rectangle& clip, RenderInfo* view); 65 | 66 | void measureSize(); 67 | 68 | void controlEvent(Control::Listener::EventType evt); 69 | 70 | virtual unsigned int drawBorder(Form* form, const Rectangle& clip, RenderInfo* view); 71 | protected: 72 | std::string _imagePath; 73 | ThemeImage* _image = NULL; 74 | }; 75 | 76 | class LoadingView : public Icon { 77 | friend class Control; 78 | float _progress = 0; 79 | protected: 80 | LoadingView(); 81 | void updateState(State state); 82 | unsigned int drawImages(Form* form, const Rectangle& clip, RenderInfo* view) override; 83 | }; 84 | 85 | } 86 | 87 | #endif -------------------------------------------------------------------------------- /modules/ai/AIAgent.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "AIAgent.h" 3 | #include "scene/Node.h" 4 | 5 | namespace mgp 6 | { 7 | 8 | AIAgent::AIAgent() 9 | : _stateMachine(NULL), _enabled(true), _listener(NULL), _next(NULL) 10 | { 11 | _stateMachine = new AIStateMachine(this); 12 | } 13 | 14 | AIAgent::~AIAgent() 15 | { 16 | SAFE_DELETE(_stateMachine); 17 | } 18 | 19 | UPtr AIAgent::create() 20 | { 21 | return UPtr(new AIAgent()); 22 | } 23 | 24 | const char* AIAgent::getId() const 25 | { 26 | if (_node) 27 | return _node->getName(); 28 | 29 | return ""; 30 | } 31 | 32 | Node* AIAgent::getNode() const 33 | { 34 | return _node; 35 | } 36 | 37 | void AIAgent::setNode(Node* node) 38 | { 39 | _node = node; 40 | } 41 | 42 | AIStateMachine* AIAgent::getStateMachine() 43 | { 44 | return _stateMachine; 45 | } 46 | 47 | bool AIAgent::isEnabled() const 48 | { 49 | return (_node && _enabled); 50 | } 51 | 52 | void AIAgent::setEnabled(bool enabled) 53 | { 54 | _enabled = enabled; 55 | } 56 | 57 | void AIAgent::setListener(Listener* listener) 58 | { 59 | _listener = listener; 60 | } 61 | 62 | void AIAgent::update(float elapsedTime) 63 | { 64 | _stateMachine->update(elapsedTime); 65 | } 66 | 67 | bool AIAgent::processMessage(AIMessage* message) 68 | { 69 | // Handle built-in message types. 70 | switch (message->_messageType) 71 | { 72 | case AIMessage::MESSAGE_TYPE_STATE_CHANGE: 73 | { 74 | // Change state message 75 | const char* stateId = message->getString(0); 76 | if (stateId) 77 | { 78 | AIState* state = _stateMachine->getState(stateId); 79 | if (state) 80 | _stateMachine->setStateInternal(state); 81 | } 82 | } 83 | break; 84 | case AIMessage::MESSAGE_TYPE_CUSTOM: 85 | break; 86 | } 87 | 88 | // Dispatch message to registered listener. 89 | if (_listener && _listener->messageReceived(message)) 90 | return true; 91 | #ifdef GP_SCRIPT_ENABLE 92 | if (_node && _node->fireScriptEvent(GP_GET_SCRIPT_EVENT(Node, messageReceived), dynamic_cast(_node), message)) 93 | return true; 94 | #endif // GP_SCRIPT_ENABLE 95 | return false; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /core/base/Buffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | #include "Buffer.h" 11 | 12 | using namespace mgp; 13 | 14 | Buffer::Buffer() : 15 | data(nullptr), _pos(0), _size(0), owner(false) { 16 | } 17 | 18 | Buffer::Buffer(size_t size) : _pos(0), _size(size), owner(true) { 19 | data = (uint8_t*)malloc(size); 20 | } 21 | 22 | Buffer::Buffer(uint8_t* data, size_t size, bool owner) : 23 | data(data), _pos(0), _size(size), owner(owner) { 24 | } 25 | 26 | Buffer::~Buffer() { 27 | if (owner) { 28 | free(data); 29 | } 30 | } 31 | 32 | 33 | size_t Buffer::write(const void* ptr, size_t size, size_t count) { 34 | size_t len = size * count; 35 | if (len > _size - _pos) { 36 | if (owner) { 37 | uint8_t *p = (uint8_t*)realloc(data, _pos+ len); 38 | if (p) { 39 | data = p; 40 | _size = _pos + len; 41 | } 42 | } else { 43 | len = _size - _pos; 44 | } 45 | } 46 | memcpy(data + _pos, ptr, len); 47 | _pos += len; 48 | return count; 49 | } 50 | 51 | size_t Buffer::read(void* ptr, size_t size, size_t count) { 52 | if (size > remaining()) { 53 | size = remaining(); 54 | } 55 | size_t len = size * count; 56 | memcpy(ptr, data + _pos, len); 57 | _pos += len; 58 | return count; 59 | } 60 | 61 | unsigned char * Buffer::readDirect(int len) { 62 | unsigned char *p = data+_pos; 63 | if (_pos <= _size - len) { 64 | _pos += len; 65 | return p; 66 | } 67 | else { 68 | _pos = _size; 69 | return p; 70 | } 71 | } 72 | 73 | void Buffer::readSlice(Buffer &out, bool copy) { 74 | out._pos = 0; 75 | size_t size = readUInt16(); 76 | out._size = size; 77 | if (_pos + size >= _size) { 78 | return; 79 | } 80 | uint8_t *data = readDirect((int)size); 81 | if (copy) { 82 | out.data = (uint8_t*)malloc(size); 83 | memcpy(out.data, data, size); 84 | out.owner = true; 85 | } else { 86 | out.data = data; 87 | out.owner = false; 88 | } 89 | } 90 | 91 | bool Buffer::seek(long int pos, int origin) { 92 | if (pos <= _size) { 93 | this->_pos = pos; 94 | return true; 95 | } 96 | return false; 97 | } 98 | -------------------------------------------------------------------------------- /doc/start.md: -------------------------------------------------------------------------------- 1 | 2 | ## 绘制三角形 3 | 4 | ``` 5 | class MainApp : public Application { 6 | void initialize() { 7 | 8 | // 创建空场景 9 | UPtr _scene = Scene::create(); 10 | 11 | // 场景三角形网格 12 | UPtr mesh = createTriangleMesh(); 13 | 14 | // 创建模型 15 | UPtr _model = Model::create(std::move(mesh)); 16 | 17 | // 添加材质 18 | Material *material = _model->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "VERTEX_COLOR"); 19 | material->getStateBlock()->setCullFace(false); 20 | 21 | // 创建结点并将模型关联到结点 22 | Node* modelNode = _scene->addNode("model"); 23 | modelNode->setDrawable(_model.dynamicCastTo()); 24 | 25 | // 设置主场景 26 | getView()->setScene(std::move(_scene)); 27 | 28 | // 初始化相机位置 29 | getView()->initCamera(false, 0.01); 30 | } 31 | }; 32 | 33 | int main() { 34 | printf("main start\n"); 35 | MainApp* instance = new MainApp(); 36 | return Platform::run(instance); 37 | } 38 | 39 | ``` 40 | 41 | 创建三角形的代码 42 | 43 | ``` 44 | static UPtr createTriangleMesh() 45 | { 46 | // 计算三角形三个点的位置 47 | float a = 0.5f; // length of the side 48 | Vector2 p1(0.0f, a / sqrtf(3.0f)); 49 | Vector2 p2(-a / 2.0f, -a / (2.0f * sqrtf(3.0f))); 50 | Vector2 p3(a / 2.0f, -a / (2.0f * sqrtf(3.0f))); 51 | 52 | // 创建顶点. 每个顶点有位置和颜色 position (x, y, z) and color (red, green, blue) 53 | float vertices[] = 54 | { 55 | (float)p1.x, (float)p1.y, 0.0f, 1.0f, 0.0f, 0.0f, 56 | (float)p2.x, (float)p2.y, 0.0f, 0.0f, 1.0f, 0.0f, 57 | (float)p3.x, (float)p3.y, 0.0f, 0.0f, 0.0f, 1.0f, 58 | }; 59 | unsigned int vertexCount = 3; 60 | 61 | //创建顶点格式 62 | VertexFormat::Element elements[] = 63 | { 64 | VertexFormat::Element(VertexFormat::POSITION, 3), 65 | VertexFormat::Element(VertexFormat::COLOR, 3) 66 | }; 67 | 68 | //创建网格 69 | UPtr mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount); 70 | if (mesh.isNull()) 71 | { 72 | GP_ERROR("Failed to create mesh."); 73 | return UPtr(NULL); 74 | } 75 | 76 | //设置形状为三角形 77 | mesh->setPrimitiveType(Mesh::TRIANGLES); 78 | 79 | //将顶点数据设置给mesh 80 | mesh->getVertexBuffer()->setData((char*)vertices, sizeof(vertices)); 81 | return mesh; 82 | } 83 | 84 | ``` 85 | 86 | -------------------------------------------------------------------------------- /core/objects/Instanced.cpp: -------------------------------------------------------------------------------- 1 | #include "Instanced.h" 2 | #include "scene/Renderer.h" 3 | 4 | using namespace mgp; 5 | 6 | Instanced::Instanced(): _instanceMatrix(NULL), _instanceCount(0), _instanceVbo(0) { 7 | 8 | } 9 | 10 | Instanced::~Instanced() { 11 | if (_instanceVbo) { 12 | Renderer::cur()->deleteBuffer(_instanceVbo); 13 | _instanceVbo = 0; 14 | } 15 | } 16 | 17 | void Instanced::setModel(UPtr model) { 18 | _model = std::move(model); 19 | if (_model.get()) { 20 | this->setLightMask(_model->getLightMask()); 21 | } 22 | } 23 | 24 | void Instanced::setInstanceMatrix(Matrix* data, int count) { 25 | _instanceMatrix.resize(16 * count); 26 | _instanceCount = count; 27 | for (int i = 0; i < count; ++i) { 28 | data[i].toArray(_instanceMatrix.data() + 16 * i); 29 | } 30 | if (!_instanceVbo) { 31 | _instanceVbo = Renderer::cur()->createBuffer(0); 32 | } 33 | Renderer::cur()->setBufferData(_instanceVbo, 0, 0, (const char*)_instanceMatrix.data(), _instanceCount * 16 * sizeof(float), 0); 34 | } 35 | 36 | void Instanced::clear() { 37 | _instanceMatrix.clear(); 38 | _instanceCount = 0; 39 | } 40 | void Instanced::add(const Matrix& matrix) { 41 | int pos = _instanceMatrix.size(); 42 | _instanceMatrix.resize(pos + 16); 43 | matrix.toArray(_instanceMatrix.data() + pos); 44 | ++_instanceCount; 45 | } 46 | void Instanced::finish() { 47 | if (!_instanceVbo) { 48 | _instanceVbo = Renderer::cur()->createBuffer(0); 49 | } 50 | Renderer::cur()->setBufferData(_instanceVbo, 0, 0, (const char*)_instanceMatrix.data(), _instanceCount * 16 * sizeof(float), 0); 51 | } 52 | 53 | void Instanced::setDrawCall(DrawCall* drawCall) { 54 | if (drawCall->_drawable) { 55 | this->setLightMask(drawCall->_drawable->getLightMask()); 56 | } 57 | drawCall->_instanceVbo = _instanceVbo; 58 | drawCall->_instanceCount = _instanceCount; 59 | drawCall->_drawable = this; 60 | } 61 | 62 | unsigned int Instanced::draw(RenderInfo *view) { 63 | int pos = view->_drawList.size(); 64 | 65 | int res = _model->draw(view); 66 | 67 | for (; pos < view->_drawList.size(); ++pos) { 68 | DrawCall& drawCall = view->_drawList[pos]; 69 | drawCall._instanceVbo = _instanceVbo; 70 | drawCall._instanceCount = _instanceCount; 71 | drawCall._drawable = this; 72 | } 73 | return res; 74 | } -------------------------------------------------------------------------------- /modules/ui/ComboBox.cpp: -------------------------------------------------------------------------------- 1 | #include "ComboBox.h" 2 | #include "base/Base.h" 3 | #include "platform/Toolkit.h" 4 | #include "MenuList.h" 5 | 6 | 7 | namespace mgp { 8 | 9 | 10 | ComboBox::ComboBox() 11 | { 12 | setPadding(4, 4, 4, 4); 13 | _className = "ComboBox"; 14 | } 15 | 16 | ComboBox::~ComboBox() 17 | { 18 | } 19 | 20 | void ComboBox::onSerialize(Serializer* serializer) { 21 | Button::onSerialize(serializer); 22 | serializer->writeList("items", _items.size()); 23 | for (std::string& it : _items) { 24 | serializer->writeString(NULL, it.c_str(), ""); 25 | } 26 | serializer->finishColloction(); 27 | serializer->writeInt("selectIndex", _selectIndex, -1); 28 | } 29 | 30 | void ComboBox::onDeserialize(Serializer* serializer) { 31 | Button::onDeserialize(serializer); 32 | int size = serializer->readList("items"); 33 | for (int i = 0; i < size; ++i) { 34 | std::string value; 35 | serializer->readString(NULL, value, ""); 36 | _items.push_back(value); 37 | } 38 | serializer->finishColloction(); 39 | int selectIndex = serializer->readInt("selectIndex", -1); 40 | setSelectIndex(selectIndex, false); 41 | } 42 | 43 | void ComboBox::setSelectIndex(int v, bool fireEvent) { 44 | if (_selectIndex != v) { 45 | _selectIndex = v; 46 | 47 | if (_selectIndex >= 0 && _selectIndex < _items.size()) { 48 | setText(_items[_selectIndex].c_str()); 49 | } 50 | else { 51 | setText(""); 52 | } 53 | if (fireEvent) this->notifyListeners(Control::Listener::SELECT_CHANGE); 54 | } 55 | } 56 | 57 | void ComboBox::controlEvent(Control::Listener::EventType evt) 58 | { 59 | Button::controlEvent(evt); 60 | 61 | switch (evt) 62 | { 63 | case Control::Listener::CLICK: 64 | UPtr list = Control::create((_id + "_menuList").c_str()); 65 | list->initItems(this->_items); 66 | auto b = this->getAbsoluteBounds(); 67 | list->setPosition(b.x, b.bottom()); 68 | list->addListener(this, Control::Listener::SELECT_CHANGE); 69 | list->show(this); 70 | break; 71 | } 72 | } 73 | 74 | void ComboBox::controlEvent(Control* control, EventType evt) { 75 | MenuList* list = dynamic_cast(control); 76 | if (list && evt == Control::Listener::SELECT_CHANGE) { 77 | setSelectIndex(list->getSelectIndex()); 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /modules/ui/FlowLayout.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOWLAYOUT_H_ 2 | #define FLOWLAYOUT_H_ 3 | 4 | #include "Layout.h" 5 | 6 | namespace mgp 7 | { 8 | 9 | /** 10 | * Defines a flow layout. 11 | * 12 | * A flow layout arranges controls in order, left-to-right, row by row and wraps. 13 | */ 14 | class FlowLayout : public Layout 15 | { 16 | //friend class Form; 17 | //friend class Container; 18 | 19 | public: 20 | 21 | /** 22 | * Get the type of this Layout. 23 | * 24 | * @return Layout::LAYOUT_FLOW 25 | */ 26 | Layout::Type getType(); 27 | 28 | /** 29 | * Returns the horizontal spacing between controls in the layout. 30 | * 31 | * @return The horizontal spacing between controls. 32 | */ 33 | int getHorizontalSpacing() const; 34 | 35 | /** 36 | * Returns the vertical spacing between controls in the layout. 37 | * 38 | * @return The vertical spacing between controls. 39 | */ 40 | int getVerticalSpacing() const; 41 | 42 | /** 43 | * Sets the spacing to add between controls in the layout. 44 | * 45 | * @param horizontalSpacing The horizontal spacing between controls. 46 | * @param verticalSpacing The vertical spacing between controls. 47 | */ 48 | void setSpacing(int horizontalSpacing, int verticalSpacing); 49 | 50 | 51 | /** 52 | * Create a FlowLayout. 53 | * 54 | * @return A FlowLayout object. 55 | */ 56 | static UPtr create(); 57 | protected: 58 | 59 | /** 60 | * Update the controls contained by the specified container. 61 | * 62 | * @param container The container to update. 63 | */ 64 | void update(const Container* container) override; 65 | 66 | float prefContentWidth(const Container* container) override; 67 | float prefContentHeight(const Container* container) override; 68 | 69 | /** 70 | * Horizontal spacing between controls. 71 | */ 72 | int _horizontalSpacing; 73 | 74 | /** 75 | * Vertical spacing between controls. 76 | */ 77 | int _verticalSpacing; 78 | 79 | private: 80 | 81 | /** 82 | * Constructor. 83 | */ 84 | FlowLayout(); 85 | 86 | /** 87 | * Constructor. 88 | */ 89 | FlowLayout(const FlowLayout& copy); 90 | 91 | /** 92 | * Destructor. 93 | */ 94 | virtual ~FlowLayout(); 95 | 96 | 97 | }; 98 | 99 | } 100 | 101 | #endif -------------------------------------------------------------------------------- /core/3rd/utf8.h: -------------------------------------------------------------------------------- 1 | #ifndef __runtime__utf8__ 2 | #define __runtime__utf8__ 3 | 4 | /* 5 | * Description: UTF-8 字符串的解码和编码函数 6 | * unicode 字符处理函数 7 | * History: yang@haipo.me, 2013/05/29, create 8 | */ 9 | 10 | # pragma once 11 | 12 | # include 13 | # include 14 | 15 | /* 16 | * 标准 C 并没有规定 wchar_t 的位数。但 GNU C Lib 保证 wchar_t 是 32 位的, 17 | * 所以可以用 wchar.h 中定义的函数来像 wchar_t 一样操纵 ucs4_t. 18 | * http://www.gnu.org/software/libc/manual/html_node/Extended-Char-Intro.html 19 | */ 20 | typedef int32_t ucs4_t; 21 | 22 | /* 23 | * 从 UTF-8 编码的字符串 *src 中读取一个 unicode 字符,并更新 *src 的值。 24 | * 25 | * 如果遇到非法 UTF-8 编码,则跳过非法部分。 26 | * 如果 illegal 参数不为 NULL, 则 *illegal 表示非法 UTF-8 编码字节数。 27 | */ 28 | ucs4_t getu8c(char **src, int *illegal); 29 | 30 | /* 31 | * 将 src 指向的 UTF-8 编码字符串解码为 unicode,放在长度为 n 的数组 des 中, 32 | * 并在末尾添加 0. 如果 des 不足以存放所有的字符,则最多保存 n - 1 个 unicode 33 | * 字符并补 0. 34 | * 35 | * 如果遇到非法 UTF-8 编码,则跳过非法部分。 36 | * 如果 illegal 不为 NULL, 则 *illegal 表示非法 UTF-8 编码的字节数。 37 | */ 38 | size_t u8decode(char const *str, ucs4_t *des, size_t n, int *illegal); 39 | 40 | /* 41 | * 将 unicode 字符 uc 编码为 UTF-8 编码,放到长度为 *left 的字符串 *des 中。 42 | * 43 | * 如果 *des 不足以存放 uc 对应的 UTF-8 字符串,返回一个负值。 44 | * 如果成功,更新 *des 和 *left 的值。 45 | */ 46 | int putu8c(ucs4_t uc, char **des, size_t *left); 47 | 48 | /* 49 | * 将以 0 结尾的 unicode 数组 us 编码为 UTF-8 字符串,放到长度为 n 的字符串 des 中。 50 | * 51 | * 负数为非法的 unicode 字符。 52 | * 如果 illegal 不为 NULL,则 *illegal 表示非法的 unicode 字符数。 53 | */ 54 | size_t u8encode(ucs4_t *us, char *des, size_t n, int *illegal); 55 | 56 | /* 57 | * 判断是否为全角字符 58 | */ 59 | int isufullwidth(ucs4_t uc); 60 | 61 | /* 62 | * 判断是否为全角字母 63 | */ 64 | int isufullwidthalpha(ucs4_t uc); 65 | 66 | /* 67 | * 判断是否为全角数字 68 | */ 69 | int isufullwidthdigit(ucs4_t uc); 70 | 71 | /* 72 | * 全角字符转半角字符。 73 | * 如果 uc 为全角字符,则返回对应的半角字符,否则返回 uc 本身。 74 | */ 75 | ucs4_t ufull2half(ucs4_t uc); 76 | 77 | /* 78 | * 半角字符转全角字符 79 | * 如果 uc 为半角字符,则返回对应的全角字符,否则返回 uc 本身。 80 | */ 81 | ucs4_t uhalf2full(ucs4_t uc); 82 | 83 | /* 84 | * 判断是否为汉字字符(中日韩越统一表意文字) 85 | */ 86 | int isuchiness(ucs4_t uc); 87 | 88 | /* 89 | * 判断是否为中文标点 90 | */ 91 | int isuzhpunct(ucs4_t uc); 92 | 93 | /* 94 | * 判断是否为日文平假名字符 95 | */ 96 | int isuhiragana(ucs4_t uc); 97 | 98 | /* 99 | * 判断是否为日文片假名字符 100 | */ 101 | int isukatakana(ucs4_t uc); 102 | 103 | /* 104 | * 判断是否为韩文字符 105 | */ 106 | int isukorean(ucs4_t uc); 107 | 108 | #endif /* defined(__runtime__utf8__) */ -------------------------------------------------------------------------------- /core/animation/AnimationController.h: -------------------------------------------------------------------------------- 1 | #ifndef ANIMATIONCONTROLLER_H_ 2 | #define ANIMATIONCONTROLLER_H_ 3 | 4 | #include "AnimationClip.h" 5 | #include "Animation.h" 6 | #include "AnimationTarget.h" 7 | #include "base/Properties.h" 8 | 9 | namespace mgp 10 | { 11 | 12 | /** 13 | * Defines a class for controlling game animation. 14 | */ 15 | class AnimationController 16 | { 17 | friend class Application; 18 | friend class Animation; 19 | friend class AnimationClip; 20 | friend class SceneLoader; 21 | 22 | public: 23 | 24 | /** 25 | * Stops all AnimationClips currently playing on the AnimationController. 26 | */ 27 | void stopAllAnimations(); 28 | 29 | static AnimationController *cur(); 30 | 31 | private: 32 | 33 | /** 34 | * The states that the AnimationController may be in. 35 | */ 36 | enum State 37 | { 38 | RUNNING, 39 | IDLE, 40 | PAUSED, 41 | STOPPED 42 | }; 43 | 44 | /** 45 | * Constructor. 46 | */ 47 | AnimationController(); 48 | 49 | /** 50 | * Constructor. 51 | */ 52 | AnimationController(const AnimationController& copy); 53 | 54 | /** 55 | * Destructor. 56 | */ 57 | ~AnimationController(); 58 | 59 | /** 60 | * Gets the controller's state. 61 | * 62 | * @return The current state. 63 | */ 64 | State getState() const; 65 | 66 | /** 67 | * Callback for when the controller is initialized. 68 | */ 69 | void initialize(); 70 | 71 | /* 72 | * Callback for when the controller is finalized. 73 | */ 74 | void finalize(); 75 | 76 | /** 77 | * Resumes the AnimationController. 78 | */ 79 | void resume(); 80 | 81 | /** 82 | * Pauses the AnimationController. 83 | */ 84 | void pause(); 85 | 86 | /** 87 | * Schedules an AnimationClip to run. 88 | */ 89 | void schedule(AnimationClip* clip); 90 | 91 | /** 92 | * Unschedules an AnimationClip. 93 | */ 94 | void unschedule(AnimationClip* clip); 95 | 96 | /** 97 | * Callback for when the controller receives a frame update event. 98 | */ 99 | void update(float elapsedTime); 100 | 101 | State _state; // The current state of the AnimationController. 102 | std::list _runningClips; // A list of running AnimationClips. 103 | }; 104 | 105 | } 106 | 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /core/base/LinkedList.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2016, chunquedong 3 | * 4 | * This file is part of cppfan project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE version 3.0 6 | * 7 | * History: 8 | * 2012-12-23 Jed Young Creation 9 | */ 10 | 11 | #ifndef _CPPF_LINKEDLIST_H_ 12 | #define _CPPF_LINKEDLIST_H_ 13 | 14 | #include "stddef.h" 15 | 16 | namespace mgp { 17 | 18 | /** 19 | * Intrusive linked list 20 | * the element must provider 'previous' and 'next' field 21 | */ 22 | template 23 | class LinkedList { 24 | T head; 25 | T &tail; 26 | int length; 27 | public: 28 | LinkedList() : tail(head), length(0) { 29 | head.previous = &head; 30 | head.next = &head; 31 | } 32 | 33 | void _clear() { 34 | tail = head; 35 | head.previous = &head; 36 | head.next = &head; 37 | length = 0; 38 | } 39 | 40 | int size() { return length; } 41 | 42 | LinkedList &add(T *elem) { 43 | T *left = tail.previous; 44 | T *right = left->next; 45 | elem->next = right; 46 | right->previous = elem; 47 | elem->previous = left; 48 | left->next = elem; 49 | ++length; 50 | return *this; 51 | } 52 | 53 | void insertFirst(T *elem) { 54 | T *left = &this->head; 55 | T *right = left->next; 56 | elem->next = right; 57 | right->previous = elem; 58 | elem->previous = left; 59 | left->next = elem; 60 | ++length; 61 | } 62 | 63 | T *getAt(int index) { 64 | T *elem; 65 | int i = 0; 66 | elem = this->head.next; 67 | while (elem != &this->tail) { 68 | if (i == index) { 69 | return elem; 70 | } 71 | elem = elem->next; 72 | ++i; 73 | } 74 | return NULL; 75 | } 76 | 77 | void insertBefore(T *elem, T *pos) { 78 | cf_assert(pos); 79 | cf_assert(elem); 80 | 81 | T *left = pos->previous; 82 | T *right = pos; 83 | elem->next = right; 84 | right->previous = elem; 85 | elem->previous = left; 86 | left->next = elem; 87 | ++length; 88 | } 89 | 90 | bool isEmpty() { 91 | return head.next == &tail; 92 | } 93 | 94 | bool remove(T *elem) { 95 | if (elem == NULL) return false; 96 | elem->previous->next = elem->next; 97 | elem->next->previous = elem->previous; 98 | --length; 99 | return true; 100 | } 101 | 102 | T *first() { return head.next; } 103 | T *last() { return tail.previous; } 104 | T *end() { return &tail; } 105 | }; 106 | 107 | } 108 | #endif // LINKEDLIST_H 109 | -------------------------------------------------------------------------------- /modules/openGL/GLRenderer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, chunquedong 3 | * 4 | * This file is part of MGP project 5 | * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 6 | * 7 | */ 8 | #ifndef GLRENDERER_H_ 9 | #define GLRENDERER_H_ 10 | 11 | #include "base/Base.h" 12 | #include "scene/Renderer.h" 13 | 14 | namespace mgp 15 | { 16 | class FrameBuffer; 17 | class GLFrameBuffer; 18 | 19 | class GLRenderer : public Renderer { 20 | friend class GLFrameBuffer; 21 | 22 | uint64_t __currentShaderProgram = 0; 23 | StateBlock stateBlock; 24 | int _drawCallCount = 0; 25 | 26 | int _width = 0; 27 | int _height = 0; 28 | 29 | GLFrameBuffer* _defaultFrameBuffer = NULL; 30 | GLFrameBuffer* _currentFrameBuffer = NULL; 31 | public: 32 | GLRenderer(); 33 | ~GLRenderer(); 34 | 35 | void init() override; 36 | 37 | void beginFrame() override; 38 | void endFrame() override; 39 | void resetState() override; 40 | unsigned int getWidth() const override; 41 | unsigned int getHeight() const override; 42 | void onResize(int w, int h) override; 43 | 44 | void clear(ClearFlags flags, const Vector4& color = Vector4::zero(), float clearDepth = 1.0, int clearStencil = 0.0) override; 45 | void setViewport(int x, int y, int w, int h) override; 46 | 47 | uint64_t createBuffer(int type) override; 48 | void setBufferData(uint64_t buffer, int type, size_t startOffset, const char* data, size_t len, int usage) override; 49 | void deleteBuffer(uint64_t buffer) override; 50 | void draw(DrawCall* drawCall) override; 51 | 52 | 53 | void updateState(StateBlock* state, int force = 1) override; 54 | 55 | void updateTexture(Texture* texture) override; 56 | void deleteTexture(Texture* texture) override; 57 | void bindTextureSampler(Texture* texture) override; 58 | 59 | ShaderProgram* createProgram(ProgramSrc* src) override; 60 | void deleteProgram(ShaderProgram*effect) override; 61 | void bindProgram(ShaderProgram* effect) override; 62 | bool bindUniform(MaterialParameter* value, Uniform* uniform, ShaderProgram* effect) override; 63 | 64 | void bindVertexAttributeObj(VertexAttributeObject* vertextAttribute); 65 | void unbindVertexAttributeObj(VertexAttributeObject* vertextAttribute); 66 | void deleteVertexAttributeObj(VertexAttributeObject* vertextAttribute); 67 | 68 | UPtr createFrameBuffer(const char* id, unsigned int width, unsigned int height, Image::Format format = Image::RGBA) override; 69 | FrameBuffer* getCurrentFrameBuffer() override; 70 | 71 | int drawCallCount() override; 72 | private: 73 | 74 | void enableDepthWrite(); 75 | 76 | }; 77 | 78 | } 79 | #endif 80 | -------------------------------------------------------------------------------- /core/animation/AnimationValue.h: -------------------------------------------------------------------------------- 1 | #ifndef ANIMATIONVALUE_H_ 2 | #define ANIMATIONVALUE_H_ 3 | 4 | #include "Animation.h" 5 | 6 | namespace mgp 7 | { 8 | 9 | /** 10 | * Defines a running animation value which can have one or more floats. 11 | */ 12 | class AnimationValue 13 | { 14 | friend class AnimationClip; 15 | friend class KeyframeChannel; 16 | 17 | public: 18 | 19 | /** 20 | * Gets the value at the specified index. 21 | * 22 | * @param index The index of the component to get the value for. 23 | * 24 | * @return The Float value at the specified index. 25 | */ 26 | Float getFloat(unsigned int index) const; 27 | 28 | /** 29 | * Sets the value at the specified index. 30 | * 31 | * @param index The index of the component to set the value for. 32 | * @param value The value to set the component to. 33 | */ 34 | void setFloat(unsigned int index, Float value); 35 | 36 | /** 37 | * Copies one or more Float values from this AnimationValue into the specified array. 38 | * 39 | * @param index The index to start copying from. 40 | * @param values Pointer to Float array to copy values into. 41 | * @param count Number of values to copy. 42 | */ 43 | void getFloats(unsigned int index, Float* values, unsigned int count) const; 44 | 45 | /** 46 | * Copies one or more Float values into the AnimationValue. 47 | * 48 | * @param index The index of the first component to set the value for. 49 | * @param values Array of values to copy into the AnimationValue. 50 | * @param count Number of values to in the array to copy in. 51 | */ 52 | void setFloats(unsigned int index, Float* values, unsigned int count); 53 | 54 | 55 | Float* getData() { return _value; } 56 | 57 | private: 58 | 59 | /** 60 | * Constructor. 61 | */ 62 | AnimationValue(); 63 | 64 | /** 65 | * Constructor. 66 | */ 67 | AnimationValue(unsigned int componentCount); 68 | 69 | /** 70 | * Constructor. 71 | */ 72 | AnimationValue(const AnimationValue& copy); 73 | 74 | /** 75 | * Destructor. 76 | */ 77 | ~AnimationValue(); 78 | 79 | /** 80 | * Hidden copy assignment operator. 81 | */ 82 | AnimationValue& operator=(const AnimationValue& v); 83 | 84 | unsigned int _componentCount; // The number of Float values for the property. 85 | unsigned int _componentSize; // The number of bytes of memory the property is. 86 | Float* _value; // The current value of the property. 87 | 88 | }; 89 | 90 | } 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /modules/physics/PhysicsGhostObject.h: -------------------------------------------------------------------------------- 1 | #ifndef PHYSICSGHOSTOBJECT_H_ 2 | #define PHYSICSGHOSTOBJECT_H_ 3 | 4 | #include "PhysicsCollisionObject.h" 5 | #include "PhysicsRigidBody.h" 6 | #include "scene/Transform.h" 7 | 8 | namespace mgp 9 | { 10 | 11 | /** 12 | * Defines a physics ghost object. 13 | * 14 | * It is a collision volume that does not participate in the physics 15 | * simulation but can be used the test against other phyics collision objects. 16 | * 17 | * @see http://gameplay3d.github.io/GamePlay/docs/file-formats.html#wiki-Collision_Objects 18 | */ 19 | class PhysicsGhostObject : public PhysicsCollisionObject, public Transform::Listener 20 | { 21 | friend class Node; 22 | friend class PhysicsController; 23 | friend class PhysicsCollisionObject; 24 | public: 25 | 26 | /** 27 | * @see PhysicsCollisionObject::getType 28 | */ 29 | PhysicsCollisionObject::Type getType() const; 30 | 31 | /** 32 | * Used to synchronize the transform between GamePlay and Bullet. 33 | */ 34 | void transformChanged(Transform* transform, long cookie); 35 | 36 | virtual void setNode(Node* node) override; 37 | protected: 38 | 39 | /** 40 | * @see PhysicsCollisionObject::getCollisionObject 41 | */ 42 | btCollisionObject* getCollisionObject() const; 43 | 44 | protected: 45 | 46 | /** 47 | * Constructor. 48 | * 49 | * @param node The node to attach the ghost object to. 50 | * @param shape The collision shape definition for the ghost object. 51 | * @param group Group identifier 52 | * @param mask Bitmask field for filtering collisions with this object. 53 | */ 54 | PhysicsGhostObject(Node* node, const PhysicsCollisionShape::Definition& shape, int group = PHYSICS_COLLISION_GROUP_DEFAULT, int mask = PHYSICS_COLLISION_MASK_DEFAULT); 55 | 56 | /** 57 | * Destructor. 58 | */ 59 | virtual ~PhysicsGhostObject(); 60 | 61 | /** 62 | * Creates a ghost object from the specified properties object. 63 | * 64 | * @param node The node to create a ghost object for; note that the node must have 65 | * a model attached to it prior to creating a ghost object for it. 66 | * @param properties The properties object defining the ghost object (must have namespace equal to 'ghost'). 67 | * @return The newly created ghost object, or NULL if the ghost object failed to load. 68 | */ 69 | static PhysicsGhostObject* create(Node* node, Properties* properties); 70 | 71 | /** 72 | * Pointer to the Bullet ghost collision object. 73 | */ 74 | btPairCachingGhostObject* _ghostObject; 75 | }; 76 | 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /modules/ui/VerticalLayout.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Base.h" 2 | #include "VerticalLayout.h" 3 | 4 | namespace mgp 5 | { 6 | 7 | VerticalLayout::VerticalLayout() : _bottomToTop(false), _spacing(0) 8 | { 9 | } 10 | 11 | VerticalLayout::~VerticalLayout() 12 | { 13 | } 14 | 15 | UPtr VerticalLayout::create() 16 | { 17 | return UPtr(new VerticalLayout()); 18 | } 19 | 20 | void VerticalLayout::setBottomToTop(bool bottomToTop) 21 | { 22 | _bottomToTop = bottomToTop; 23 | } 24 | 25 | bool VerticalLayout::getBottomToTop() 26 | { 27 | return _bottomToTop; 28 | } 29 | 30 | Layout::Type VerticalLayout::getType() 31 | { 32 | return Layout::LAYOUT_VERTICAL; 33 | } 34 | 35 | int VerticalLayout::getSpacing() const 36 | { 37 | return _spacing; 38 | } 39 | 40 | void VerticalLayout::setSpacing(int spacing) 41 | { 42 | _spacing = spacing; 43 | } 44 | 45 | void VerticalLayout::update(const Container* container) 46 | { 47 | GP_ASSERT(container); 48 | 49 | // Need border, padding. 50 | //Border border = container->getBorder(container->getState()); 51 | Padding padding = container->getPadding(); 52 | 53 | float yPosition = 0; 54 | 55 | const std::vector& controls = container->getControls(); 56 | 57 | int i, end, iter; 58 | if (_bottomToTop) 59 | { 60 | i = (int)controls.size() - 1; 61 | end = -1; 62 | iter = -1; 63 | } 64 | else 65 | { 66 | i = 0; 67 | end = (int)controls.size(); 68 | iter = 1; 69 | } 70 | 71 | while (i != end) 72 | { 73 | Control* control = controls.at(i); 74 | GP_ASSERT(control); 75 | 76 | if (control->isVisible()) 77 | { 78 | const Rectangle& bounds = control->getBounds(); 79 | const Margin& margin = control->getMargin(); 80 | 81 | yPosition += margin.top; 82 | 83 | control->setYInternal(yPosition); 84 | 85 | yPosition += bounds.height + margin.bottom + _spacing; 86 | } 87 | 88 | i += iter; 89 | } 90 | } 91 | 92 | float VerticalLayout::prefContentHeight(const Container* container) { 93 | // Size ourself to tightly fit the height of our children 94 | float height = 0; 95 | for (size_t i = 0, count = container->getControls().size(); i < count; ++i) 96 | { 97 | Control* ctrl = container->getControls()[i]; 98 | if (ctrl->isVisible() && !ctrl->isHeightPercentage()) 99 | { 100 | float h = ctrl->getMeasureBufferedHeight(); 101 | height += h + _spacing; 102 | } 103 | } 104 | return height; 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /doc/ui.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## GUI 4 | 5 | mgp自带UI库,支持常用的控件。 6 | 新版本使用wase库,自带的GUi库以后将不再维护。 7 | 8 | ``` 9 | UPtr form = Form::create(); 10 | form->getContent()->setSize(600, 700); 11 | form->getContent()->setLayout(Layout::LAYOUT_FLOW); 12 | 13 | UPtr