├── .gitignore
├── 3rdParty
└── pyenv-2.5.7.tar.gz
├── LICENSE
├── README.rst
├── README_assimpy.rst
├── README_glass.rst
├── README_glass_engine.rst
├── assimpy
├── LICENSE
├── README_PYPI.md
├── __init__.py
├── __pyinstaller
│ ├── __init__.py
│ ├── assimp
│ │ └── LICENSE
│ ├── hook-assimpy.py
│ └── pybind11
│ │ └── LICENSE
├── assimp-5.4.3.zip
├── assimpy_ext.cpp
├── assimpy_ext.h
├── module.cpp
└── pybind11-2.13.6.zip
├── auto_format.py
├── build_assimpy.py
├── build_glass.py
├── build_glass_engine.py
├── glass
├── ACBO.py
├── AttrList.py
├── BO.py
├── Block.py
├── CSRMat.py
├── CodeCompressor
│ ├── CodeCompressor.py
│ ├── ShaderBuiltins.py
│ ├── ShaderSyntaxTokens.py
│ ├── __init__.py
│ ├── generate_code.py
│ ├── minifyc.py
│ └── pcpp
│ │ ├── LICENSE
│ │ ├── __init__.py
│ │ ├── evaluator.py
│ │ ├── lextab.py
│ │ ├── parser.py
│ │ ├── parsetab.py
│ │ ├── pcmd.py
│ │ ├── ply
│ │ ├── __init__.py
│ │ ├── cpp.py
│ │ ├── ctokens.py
│ │ ├── lex.py
│ │ ├── yacc.py
│ │ └── ygen.py
│ │ └── preprocessor.py
├── ComputeProgram.py
├── CustomLiteral.py
├── DictList.py
├── EBO.py
├── FBO.py
├── FBOAttachment.py
├── GLConfig.py
├── GLInfo.py
├── GLObject.py
├── GPUProgram.py
├── GlassConfig.py
├── ImageLoader.py
├── ImageUnits.py
├── Increment.py
├── Indices.py
├── Instances.py
├── LICENSE
├── MetaInstancesRecorder.py
├── RBO.py
├── README_PYPI.md
├── RenderHints.py
├── SSBO.py
├── SSUBO.py
├── SameTypeList.py
├── ShaderParser.py
├── ShaderProgram.py
├── ShaderStorageBlock.py
├── Shaders.py
├── TextLoader.py
├── TextureUnits.py
├── UBO.py
├── Uniform.py
├── UniformBlock.py
├── VAO.py
├── VBO.py
├── Vertices.py
├── WeakDict.py
├── WeakList.py
├── WeakRef.py
├── WeakSet.py
├── __init__.py
├── __pyinstaller
│ ├── __init__.py
│ └── hook-glass.py
├── callback_vec.py
├── download.py
├── glsl
│ ├── draw_frame.vert
│ └── shadertoy_template.frag
├── helper.py
├── iimage2D.py
├── image2D.py
├── isampler2D.py
├── isampler2DMS.py
├── sampler2D.py
├── sampler2DArray.py
├── sampler2DMS.py
├── samplerCube.py
├── uimage2D.py
├── usampler2D.py
├── usampler2DMS.py
└── utils.py
├── glass_engine
├── AffineTransform.py
├── Animations
│ ├── Animation.py
│ ├── AnimationGroup.py
│ ├── Chronoscope.py
│ ├── EasingCurve.py
│ ├── ParallelAnimation.py
│ ├── SequentialAnimation.py
│ └── __init__.py
├── Background.py
├── BasicScene.py
├── Camera.py
├── ColorMap.py
├── Fog.py
├── Frame.py
├── Geometries
│ ├── Box.py
│ ├── Circle.py
│ ├── CircleFace.py
│ ├── Cone.py
│ ├── ConeSide.py
│ ├── ConeTrustum.py
│ ├── ConeTrustumSide.py
│ ├── CoordSys.py
│ ├── Cylinder.py
│ ├── CylinderSide.py
│ ├── CylindricalFSurf.py
│ ├── Dodecahedron.py
│ ├── EllipseFace.py
│ ├── Extruder.py
│ ├── FSurf.py
│ ├── Floor.py
│ ├── Hexahedron.py
│ ├── HollowRPolygonFace.py
│ ├── Icosahedron.py
│ ├── Icosphere.py
│ ├── ImageQuad.py
│ ├── Octahedron.py
│ ├── Point.py
│ ├── Points.py
│ ├── Polyline.py
│ ├── Prism.py
│ ├── PrismSide.py
│ ├── Pyramid.py
│ ├── PyramidSide.py
│ ├── PyramidTrustum.py
│ ├── PyramidTrustumSide.py
│ ├── RPolygonFace.py
│ ├── RectFace.py
│ ├── Rotator.py
│ ├── Sphere.py
│ ├── SphericalCap.py
│ ├── SphericalCapTop.py
│ ├── SphericalFSurf.py
│ ├── Surf.py
│ ├── Tetrahedron.py
│ ├── Torus.py
│ ├── TorusFace.py
│ ├── TrefoilKnot.py
│ └── __init__.py
├── GlassEngineConfig.py
├── LICENSE
├── Lights
│ ├── DirLight.py
│ ├── Light.py
│ ├── PointLight.py
│ ├── SpotLight.py
│ └── __init__.py
├── Manipulators
│ ├── Manipulator.py
│ ├── ModelViewManipulator.py
│ ├── SceneRoamManipulator.py
│ └── __init__.py
├── Material.py
├── Mesh.py
├── Model.py
├── Pivot.py
├── PostProcessEffects
│ ├── ACESToneMapper.py
│ ├── BloomEffect.py
│ ├── DOFEffect.py
│ ├── ExposureAdaptor.py
│ ├── FXAAEffect.py
│ ├── GaussBlur.py
│ ├── KernelFilter.py
│ ├── LUTEffect.py
│ ├── MedianBlur.py
│ ├── MulFilter.py
│ ├── PostProcessEffect.py
│ ├── PostProcessEffects.py
│ ├── SSAOEffect.py
│ ├── ShaderEffect.py
│ └── __init__.py
├── README_PYPI.md
├── Renderers
│ ├── CommonRenderer.py
│ ├── DeferredRenderer.py
│ ├── ForwardRenderer.py
│ ├── Renderer.py
│ └── __init__.py
├── Scene.py
├── SceneNode.py
├── Screens
│ ├── PyQt5Screen.py
│ ├── PyQt6Screen.py
│ ├── PySide2Screen.py
│ ├── PySide6Screen.py
│ ├── QtScreen.py
│ └── __init__.py
├── SkyBox.py
├── SkyDome.py
├── SlideAverageFilter.py
├── VideoRecorder.py
├── WeightedIntegrator.py
├── __init__.py
├── __pyinstaller
│ ├── __init__.py
│ └── hook-glass_engine.py
├── algorithm.py
├── glsl
│ ├── Lights
│ │ ├── DirLight.glsl
│ │ ├── DirLight_lighting.glsl
│ │ ├── DirLight_shadow_mapping.glsl
│ │ ├── Lights.glsl
│ │ ├── Lights_lighting.glsl
│ │ ├── PointLight.glsl
│ │ ├── PointLight_lighting.glsl
│ │ ├── PointLight_shadow_mapping.glsl
│ │ ├── SpotLight.glsl
│ │ ├── SpotLight_lighting.glsl
│ │ └── SpotLight_shadow_mapping.glsl
│ ├── Pipelines
│ │ ├── DirLight_depth
│ │ │ ├── DirLight_depth.frag
│ │ │ ├── DirLight_depth.geom
│ │ │ ├── DirLight_depth.vert
│ │ │ ├── DirLight_depth_lines.geom
│ │ │ └── DirLight_depth_points.geom
│ │ ├── OIT_blend.frag
│ │ ├── PointLight_depth
│ │ │ ├── PointLight_depth.frag
│ │ │ ├── PointLight_depth.geom
│ │ │ ├── PointLight_depth.vert
│ │ │ ├── PointLight_depth_lines.geom
│ │ │ └── PointLight_depth_points.geom
│ │ ├── SpotLight_depth
│ │ │ ├── SpotLight_depth.frag
│ │ │ ├── SpotLight_depth.geom
│ │ │ ├── SpotLight_depth_lines.geom
│ │ │ └── SpotLight_depth_points.geom
│ │ ├── deferred_rendering
│ │ │ ├── deferred_rendering.frag
│ │ │ ├── draw_points_to_gbuffer.frag
│ │ │ ├── draw_to_gbuffer.frag
│ │ │ ├── read_from_gbuffer.glsl
│ │ │ └── write_to_gbuffer.glsl
│ │ ├── draw_frame.frag
│ │ ├── draw_geometry
│ │ │ ├── draw_geometry.frag
│ │ │ ├── draw_geometry.geom
│ │ │ ├── draw_geometry.vert
│ │ │ ├── draw_geometry_lines.vert
│ │ │ ├── draw_geometry_points.frag
│ │ │ └── draw_geometry_points.vert
│ │ ├── env_mapping
│ │ │ ├── env_OIT_blend.frag
│ │ │ ├── gen_env_map.frag
│ │ │ ├── gen_env_map.geom
│ │ │ ├── gen_env_map.vert
│ │ │ ├── gen_env_map_lines.geom
│ │ │ ├── gen_env_map_points.frag
│ │ │ ├── gen_env_map_points.geom
│ │ │ └── gen_env_map_points.vert
│ │ ├── forward_rendering
│ │ │ ├── forward_draw_lines.vert
│ │ │ ├── forward_draw_points.frag
│ │ │ ├── forward_draw_points.vert
│ │ │ ├── forward_rendering.frag
│ │ │ ├── forward_rendering.geom
│ │ │ └── forward_rendering.vert
│ │ ├── skybox
│ │ │ ├── skybox.frag
│ │ │ └── skybox.vert
│ │ └── skydome
│ │ │ ├── skydome.frag
│ │ │ └── skydome.vert
│ ├── PostProcessEffects
│ │ ├── ACES_tone_mapper.glsl
│ │ ├── FXAA.frag
│ │ ├── FXAA_array.frag
│ │ ├── FXAA_cube.frag
│ │ ├── SSAO_visibility.glsl
│ │ ├── bloom_downsampling.frag
│ │ ├── bloom_mix.frag
│ │ ├── bloom_upsampling.frag
│ │ ├── dof.frag
│ │ ├── exposure_adaptor.glsl
│ │ ├── gauss_blur.frag
│ │ ├── gauss_blur_array.frag
│ │ ├── gauss_blur_cube.frag
│ │ ├── kernel_filter.frag
│ │ ├── kernel_filter_array.frag
│ │ ├── kernel_filter_cube.frag
│ │ ├── lut.glsl
│ │ ├── median_gray_blur5.glsl
│ │ ├── mul_filter.glsl
│ │ ├── shader_effect_template.frag
│ │ ├── slit_stretch.glsl
│ │ ├── star_field.glsl
│ │ └── water_wave.glsl
│ ├── ShadingModels
│ │ ├── CookTorrance.glsl
│ │ ├── Flat.glsl
│ │ ├── Fresnel.glsl
│ │ ├── Gouraud.glsl
│ │ ├── Lambert.glsl
│ │ ├── Minnaert.glsl
│ │ ├── OrenNayar.glsl
│ │ ├── Phong.glsl
│ │ ├── PhongBlinn.glsl
│ │ ├── Toon.glsl
│ │ ├── lighting.glsl
│ │ └── rim.glsl
│ ├── check.py
│ └── include
│ │ ├── Camera.glsl
│ │ ├── FXAA.glsl
│ │ ├── FresnelRefract.glsl
│ │ ├── InternalMaterial.glsl
│ │ ├── Material.glsl
│ │ ├── OIT.glsl
│ │ ├── ShadingInfo.glsl
│ │ ├── background.glsl
│ │ ├── env_mapping.glsl
│ │ ├── fog.glsl
│ │ ├── image_read_write.glsl
│ │ ├── limits.glsl
│ │ ├── math.glsl
│ │ ├── parallax_mapping.glsl
│ │ ├── quat.glsl
│ │ ├── random.glsl
│ │ ├── sampling.glsl
│ │ ├── shading_all.glsl
│ │ ├── soft.glsl
│ │ ├── tex_coord.glsl
│ │ └── transform.glsl
├── images
│ ├── glass_engine_logo256.png
│ ├── glass_engine_logo411.png
│ ├── glass_engine_logo64.png
│ └── start.png
└── lut.py
├── linux_install_python.sh
├── mac_install_python.sh
├── requirements.txt
├── setup_assimpy.py
├── setup_glass.py
├── setup_glass_engine.py
├── static_check.py
├── to-do-list.txt
├── upload_assimpy.py
├── upload_glass.py
├── upload_glass_engine.py
└── windows_install_python.bat
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | __glcache__
3 | workspace
4 | *.pyd/*
5 | build
6 | dist
7 | *.egg-info
8 | *.avi
9 | *.mp4
10 | .vscode
11 | upload.bat
12 | generate_md5.py
13 | used_shaders
14 | setup.py
15 | MANIFEST.in
16 | .python-version
17 | .DS_Store
18 | assimpy/assimp-*/*
19 | assimpy/pybind11-*/*
20 | assimpy/assimp/*
21 | assimpy/pybind11/*
22 | *.sqlite
23 | glass/CodeCompressor/tree-sitter-glsl/src/*
24 | test_*
25 | .venv*
26 | *.spv
27 | note.txt
28 | glass_engine/glsl/temp
--------------------------------------------------------------------------------
/3rdParty/pyenv-2.5.7.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/3rdParty/pyenv-2.5.7.tar.gz
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023-2025 王炳辉 (binghui.wang@foxmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Glass Engine -- 易用的 Python 3D 渲染引擎
2 | ================================================================
3 |
4 | .. figure:: glass_engine/images/glass_engine_logo256.png
5 | :align: center
6 | :alt: glass_engine_logo
7 | :width: 256px
8 |
9 |
10 | **Glass Engine** 是一个相当易用的 Python 实时 3D 渲染引擎,完全免费开源。使用 **Glass Engine** 你可以轻松地在你的 Python 界面程序中嵌入可交互的 3D 画面。
11 |
12 | 首先,使用以下命令即可完成对 **Glass Engine** 的安装,
13 |
14 | ::
15 |
16 | pip install glass-engine
17 |
18 | 如果你是中国区用户,使用以下命令则可以加速安装过程:
19 |
20 | ::
21 |
22 | pip install glass-engine -i https://mirrors.aliyun.com/pypi/simple
23 |
24 | 接下来,让我们通过一个简单例子来直观感受一下 **Glass Engine** 的使用过程:
25 |
26 | .. highlight:: python3
27 |
28 | ::
29 |
30 | from glass_engine import *
31 | from glass_engine.Geometries import * # 导入所有的基本几何体
32 |
33 | scene, camera, light, floor = SceneRoam() # 创建基本场景
34 |
35 | sphere = Sphere() # 创建一个球体模型
36 | sphere.position.z = 1 # 设置球体位置
37 | scene.add(sphere) # 将球体添加到场景中
38 |
39 | camera.screen.show() # 相机显示屏显示渲染结果
40 |
41 | 上述代码首先使用 ``SceneRoam`` 创建出一个基本场景,包括了相机、光源、地板,然后往场景中添加了一个球体模型,最后将相机观察到的视口显示出来。
42 |
43 | 可以看出,使用 **Glass Engine** 创建 3D 场景无需自定义任何类和任何函数,仅通过对象创建、方法调用的顺序程序结构就可完成场景的构建和显示,由此体现出 **Glass Engine** 高度的易用性,这也是 **Glass Engine** 相比于其他同类 3D 引擎的优势所在。
44 |
45 | 运行上述程序,你将得到下图所示结果:
46 |
47 | .. figure:: glass_engine/images/start.png
48 | :alt: glass_engine_simple_scene
49 | :align: center
50 | :width: 400px
51 |
52 |
53 | 你可以通过鼠标右键拖动以旋转视角,还可通过键盘按键 :kbd:`W` :kbd:`A` :kbd:`S` :kbd:`D` :kbd:`E` :kbd:`C` 来在场景中漫游:
54 |
55 | - :kbd:`A` 向左移动,:kbd:`D` 向右移动
56 | - :kbd:`W` 向前移动,:kbd:`S` 向后移动
57 | - :kbd:`E` 向上移动,:kbd:`C` 向下移动
58 |
59 | 怎么样,是不是很简单、直观、易用?如果你感兴趣的话,就让我们开始接下来的 3D 渲染之旅吧!
60 |
61 | - `文档 `_
62 | - `PyPI 索引 `_
63 |
--------------------------------------------------------------------------------
/README_assimpy.rst:
--------------------------------------------------------------------------------
1 | Assimpy -- 为 Glass Engine 提供 3D 模型加载功能
2 | ================================================================
3 |
4 | **Assimpy** 为 **Glass Engine** 的子项目,是 Assimp 项目的 Python 绑定,为 Glass Engine 提供 3D 模型加载功能。
5 | 仅提供 ``load(file_name:str, flags:int)->Model`` 函数用于加载模型。其优势在于:
6 |
7 | - 使用 assimp 加载模型后,不做任何的中间类型拷贝,直接将原生内存 buffer 暴露给 python
8 | - 支持内置纹理加载
9 |
10 | 你可以在任意需要加载 3D 模型的时候使用 **Assimpy**,并在其源码中找见加载上来的模型结构,
11 | 但不建议你这么做。因为其初衷是为 **Glass Engine** 提供 3D 模型的加载功能,
12 | 因此不过多介绍 **Assimpy** 的用法,欢迎访问 **Glass Engine** 项目:
13 |
14 | - `文档 `_
15 | - `Github 项目主页 `_
16 | - `Gitee 项目主页 `_
17 | - `PyPI 索引 `_
18 |
19 | **Glass Engine** 中的模型加载功能用法请参考 `Glass Engine 文档的模型加载章节 `_
--------------------------------------------------------------------------------
/README_glass.rst:
--------------------------------------------------------------------------------
1 | Glass -- 为 Glass Engine 提供 OpenGL 易用封装
2 | ================================================================
3 |
4 | **Glass** 为 **Glass Engine** 的子项目,为 OpenGL Assistant 的缩写。
5 | OpenGL 函数的底层接口的设计为了跨平台,牺牲了易用性。
6 | 为了使 OpenGL 的调用对 Python 用户更友好,封装了 **Glass** 库。
7 | 该库简化了大量 OpenGL 概念以及函数调用方法,几项重点简化包括:
8 |
9 | - 支持从文件编译 Shader,支持在 Shader 中使用 ``include``,并将报错行号指向真实的 include 文件;
10 | - ShaderProgram 自动采用增量编译策略,仅当文件和依赖改变时重新编译;
11 | - 设置 Uniform/Uniform Block/Shader Storage Block 变量时,Python 对象可直接赋值给 Shader 中的对应结构变量;
12 | - 提供 Vertices/Indices 类对顶点和索引进行管理,用户无需接触 VBO/VAO/EBO 等直接操作显存的概念;
13 | - 变化的顶点和索引采用增量拷贝算法同步到显存,提高拷贝效率。
14 |
15 | 下面是一段不完整的代码展示了 glass 操作 OpenGL 的方法:
16 |
17 | .. highlight:: python3
18 |
19 | ::
20 |
21 | from glass import *
22 |
23 | # 在一个合法的 OpenGL 上下文中:
24 |
25 | # 创建 shader 程序
26 | program = ShaderProgram()
27 | program.compile("path/to/vertex_shader.vert")
28 | program.compile("path/to/fragment_shader.frag")
29 | # 上述两个 compile 并不会每次运行都编译,仅首次以及 Shader 文件修改后才编译
30 | # shader 文件中可含有 #include 语法
31 |
32 | # 将 Python 变量 pyvar 直接赋值给 Shader 端的 Uniform 结构体变量 uniform_var
33 | # 只要 Python 变量中含有对应的属性
34 | program["uniform_var"] = pyvar
35 |
36 | # 纹理 uniform 变量可用如下方法赋值
37 | # 对用户隐藏纹理单元概念
38 | program["sampler_var"] = sampler2D("path/to/image.png")
39 |
40 | # 创建顶点数组
41 | vertices = Vertices() # 像 list 一样操作 vertices,只不过元素只能为 Vertex 类型
42 |
43 | # 添加顶点
44 | vertices.append(Vertex(position=glm.vec2(-0.5,-0.5), color=glm.vec3(1,0,0)))
45 | vertices.append(Vertex(position=glm.vec2(0.5,-0.5), color=glm.vec3(0,1,0)))
46 | vertices.append(Vertex(position=glm.vec2(0,0.5), color=glm.vec3(0,0,1)))
47 | # 构建顶点 Vertex 时,属性名可为任意值
48 | # 只要在 vertex shader 中的 layout 指定了该属性名并且类型匹配
49 |
50 | # 创建索引数组
51 | indices = Indices() # 像 list 一样操作 indices,只不过元素只能为 glm.uvec3 类型
52 | indices.append(glm.uvec3(0, 1, 2))
53 |
54 | # 绘制三角形
55 | program.draw_triangles(vertices=vertices, indices=indices)
56 |
57 | # vertices 和 indices 可在任意时刻动态修改内部元素,以及动态增加删除元素
58 | # 所有修改将在下次绘制时同步到显存
59 |
60 | 你可以在任意需要使用 OpenGL 的地方使用 **Glass**,
61 | 但其初衷是为 **Glass Engine** 提供 OpenGL 的封装,因此不过多介绍 **Glass** 的用法,欢迎访问 **Glass Engine** 项目:
62 |
63 | - `文档 `_
64 | - `Github 项目主页 `_
65 | - `Gitee 项目主页 `_
66 | - `PyPI 索引 `_
67 |
--------------------------------------------------------------------------------
/README_glass_engine.rst:
--------------------------------------------------------------------------------
1 | Glass Engine -- 易用的 Python 3D 渲染引擎
2 | ================================================================
3 |
4 | .. figure:: glass_engine/images/glass_engine_logo256.png
5 | :align: center
6 | :alt: glass_engine_logo
7 | :width: 256px
8 |
9 |
10 | **Glass Engine** 是一个相当易用的 Python 实时 3D 渲染引擎,完全免费开源。使用 **Glass Engine** 你可以轻松地在你的 Python 界面程序中嵌入可交互的 3D 画面。
11 |
12 | 首先,使用以下命令即可完成对 **Glass Engine** 的安装,
13 |
14 | ::
15 |
16 | pip install glass-engine
17 |
18 | 如果你是中国区用户,使用以下命令则可以加速安装过程:
19 |
20 | ::
21 |
22 | pip install glass-engine -i https://mirrors.aliyun.com/pypi/simple
23 |
24 | 接下来,让我们通过一个简单例子来直观感受一下 **Glass Engine** 的使用过程:
25 |
26 | .. highlight:: python3
27 |
28 | ::
29 |
30 | from glass_engine import *
31 | from glass_engine.Geometries import * # 导入所有的基本几何体
32 |
33 | scene, camera, light, floor = SceneRoam() # 创建基本场景
34 |
35 | sphere = Sphere() # 创建一个球体模型
36 | sphere.position.z = 1 # 设置球体位置
37 | scene.add(sphere) # 将球体添加到场景中
38 |
39 | camera.screen.show() # 相机显示屏显示渲染结果
40 |
41 | 上述代码首先使用 ``SceneRoam`` 创建出一个基本场景,包括了相机、光源、地板,然后往场景中添加了一个球体模型,最后将相机观察到的视口显示出来。
42 |
43 | 可以看出,使用 **Glass Engine** 创建 3D 场景无需自定义任何类和任何函数,仅通过对象创建、方法调用的顺序程序结构就可完成场景的构建和显示,由此体现出 **Glass Engine** 高度的易用性,这也是 **Glass Engine** 相比于其他同类 3D 引擎的优势所在。
44 |
45 | 运行上述程序,你将得到下图所示结果:
46 |
47 | .. figure:: glass_engine/images/start.png
48 | :alt: glass_engine_simple_scene
49 | :align: center
50 | :width: 400px
51 |
52 |
53 | 你可以通过鼠标右键拖动以旋转视角,还可通过键盘按键 :kbd:`W` :kbd:`A` :kbd:`S` :kbd:`D` :kbd:`E` :kbd:`C` 来在场景中漫游:
54 |
55 | - :kbd:`A` 向左移动,:kbd:`D` 向右移动
56 | - :kbd:`W` 向前移动,:kbd:`S` 向后移动
57 | - :kbd:`E` 向上移动,:kbd:`C` 向下移动
58 |
59 | 怎么样,是不是很简单、直观、易用?如果你感兴趣的话,就让我们开始接下来的 3D 渲染之旅吧!
60 |
61 | - `文档 `_
62 | - `PyPI 索引 `_
63 |
--------------------------------------------------------------------------------
/assimpy/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023-2025 王炳辉 (binghui.wang@foxmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/assimpy/README_PYPI.md:
--------------------------------------------------------------------------------
1 | # Assimpy -- 为 Glass Engine 提供 3D 模型加载功能
2 |
3 | **Assimpy** 为 **Glass Engine** 的子项目,是 Assimp 项目的 Python 绑定,为 Glass Engine 提供 3D 模型加载功能。
4 | 仅提供 ``load(file_name:str, flags:int)->Model`` 函数用于加载模型。其优势在于:
5 |
6 | * 使用 assimp 加载模型后,不做任何的中间类型拷贝,直接将原生内存 buffer 暴露给 python
7 | * 支持内置纹理加载
8 |
9 | 你可以在任意需要加载 3D 模型的时候使用 **Assimpy**,并在其源码中找见加载上来的模型结构,
10 | 但不建议你这么做。因为其初衷是为 **Glass Engine** 提供 3D 模型的加载功能,
11 | 因此不过多介绍 **Assimpy** 的用法,欢迎访问 **Glass Engine** 项目:
12 |
13 | * 文档:
14 | * Github 项目主页:
15 | * Gitee 项目主页:
16 | * PyPI 索引:
17 |
18 | **Glass Engine** 中的模型加载功能用法请参考:
19 |
20 |
--------------------------------------------------------------------------------
/assimpy/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "5.4.3.3"
2 |
3 | from assimpy_ext import load
--------------------------------------------------------------------------------
/assimpy/__pyinstaller/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | def get_hook_dirs():
4 | return [os.path.dirname(os.path.abspath(__file__)).replace("\\", "/")]
--------------------------------------------------------------------------------
/assimpy/__pyinstaller/hook-assimpy.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | self_folder = os.path.dirname(os.path.abspath(__file__))
4 | datas = [
5 | (os.path.abspath(self_folder + "/../LICENSE").replace("\\", "/"), "assimpy"),
6 | (os.path.abspath(self_folder + "/assimp/LICENSE").replace("\\", "/"), "assimpy/assimp"),
7 | (os.path.abspath(self_folder + "/pybind11/LICENSE").replace("\\", "/"), "assimpy/pybind11")
8 | ]
9 |
--------------------------------------------------------------------------------
/assimpy/__pyinstaller/pybind11/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Wenzel Jakob , All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | 3. Neither the name of the copyright holder nor the names of its contributors
14 | may be used to endorse or promote products derived from this software
15 | without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
29 | external contributions to this project including patches, pull requests, etc.
30 |
--------------------------------------------------------------------------------
/assimpy/assimp-5.4.3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/assimpy/assimp-5.4.3.zip
--------------------------------------------------------------------------------
/assimpy/pybind11-2.13.6.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/assimpy/pybind11-2.13.6.zip
--------------------------------------------------------------------------------
/auto_format.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 |
4 |
5 | def auto_format(folder_name):
6 | subprocess.call([sys.executable, "-m", "black", folder_name])
7 |
8 |
9 | auto_format("glass")
10 | auto_format("glass_engine")
11 |
--------------------------------------------------------------------------------
/build_glass.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 | import os
4 | import shutil
5 |
6 | try:
7 | if os.path.isdir("build"):
8 | shutil.rmtree("build")
9 |
10 | if os.path.isdir("python_glass.egg-info"):
11 | shutil.rmtree("python_glass.egg-info")
12 |
13 | with open("README_glass.rst", "r", encoding="utf-8") as in_file:
14 | content = in_file.read()
15 |
16 | with open("README.rst", "w", encoding="utf-8") as out_file:
17 | out_file.write(content)
18 |
19 | with open("setup_glass.py", "r", encoding="utf-8") as in_file:
20 | content = in_file.read()
21 |
22 | with open("setup.py", "w", encoding="utf-8") as out_file:
23 | out_file.write(content)
24 |
25 | with open("MANIFEST.in", "w", encoding="utf-8") as out_file:
26 | out_file.write(
27 | """include glass/README_PYPI.md
28 | include glass/LICENSE
29 | include glass/CodeCompressor/pcpp/LICENSE
30 | """)
31 |
32 | subprocess.call([sys.executable, "setup.py", "sdist", "bdist_wheel"])
33 | finally:
34 | with open("README_glass_engine.rst", "r", encoding="utf-8") as in_file:
35 | content = in_file.read()
36 |
37 | with open("README.rst", "w", encoding="utf-8") as out_file:
38 | out_file.write(content)
--------------------------------------------------------------------------------
/build_glass_engine.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 | import os
4 | import shutil
5 |
6 | if os.path.isdir("build"):
7 | shutil.rmtree("build")
8 |
9 | if os.path.isdir("glass_engine.egg-info"):
10 | shutil.rmtree("glass_engine.egg-info")
11 |
12 | with open("README_glass_engine.rst", "r", encoding="utf-8") as in_file:
13 | content = in_file.read()
14 |
15 | with open("README.rst", "w", encoding="utf-8") as out_file:
16 | out_file.write(content)
17 |
18 | with open("setup_glass_engine.py", "r", encoding="utf-8") as in_file:
19 | content = in_file.read()
20 |
21 | with open("setup.py", "w", encoding="utf-8") as out_file:
22 | out_file.write(content)
23 |
24 | with open("MANIFEST.in", "w", encoding="utf-8") as out_file:
25 | out_file.write(
26 | """include glass_engine/images/glass_engine_logo256.png
27 | include glass_engine/images/start.png
28 | include glass_engine/README_PYPI.md
29 | include glass_engine/LICENSE
30 | """)
31 |
32 | subprocess.call([sys.executable, "setup.py", "sdist", "bdist_wheel"])
33 |
--------------------------------------------------------------------------------
/glass/ACBO.py:
--------------------------------------------------------------------------------
1 | from .BO import BO
2 | from .utils import capacity_of
3 |
4 | from OpenGL import GL
5 | import numpy as np
6 |
7 |
8 | class ACBO(BO):
9 |
10 | _basic_info = {
11 | "gen_func": GL.glGenBuffers,
12 | "bind_func": GL.glBindBuffer,
13 | "del_func": GL.glDeleteBuffers,
14 | "target_type": GL.GL_ATOMIC_COUNTER_BUFFER,
15 | "binding_type": GL.GL_ATOMIC_COUNTER_BUFFER_BINDING,
16 | "need_number": True,
17 | }
18 |
19 | _binding_points_pool = None
20 |
21 | _ACBO_map = {}
22 |
23 | def __init__(self) -> None:
24 | BO.__init__(self)
25 |
26 | @staticmethod
27 | def set(binding: int, offset: int, value: int) -> None:
28 | acbo = None
29 | if binding not in ACBO._ACBO_map:
30 | acbo = ACBO()
31 | acbo.malloc(4 * capacity_of(offset / 4), GL.GL_DYNAMIC_COPY)
32 | ACBO._ACBO_map[binding] = acbo
33 | else:
34 | acbo = ACBO._ACBO_map[binding]
35 | if offset + 4 > acbo.nbytes:
36 | temp_bo = ACBO()
37 | temp_bo.malloc(4 * capacity_of(offset / 4), GL.GL_DYNAMIC_COPY)
38 | acbo.copy_to(0, acbo.nbytes, temp_bo, 0)
39 | acbo.delete()
40 | acbo = temp_bo
41 | ACBO._ACBO_map[binding] = acbo
42 |
43 | acbo.bind_to_point(binding)
44 | acbo.bufferSubData(offset, 4, np.array([int(value)], dtype=np.uint32))
45 |
46 | @staticmethod
47 | def get(binding: int, offset: int) -> int:
48 | if binding not in ACBO._ACBO_map:
49 | return 0
50 |
51 | acbo = ACBO._ACBO_map[binding]
52 | acbo.bind()
53 | data = np.array([0], np.uint32)
54 | GL.glGetBufferSubData(GL.GL_ATOMIC_COUNTER_BUFFER, offset, 4, data)
55 | return int(data[0])
56 |
57 | def bind_to_point(self, binding_point: int) -> None:
58 | self.bind()
59 | GL.glBindBufferBase(GL.GL_ATOMIC_COUNTER_BUFFER, binding_point, self._id)
60 |
--------------------------------------------------------------------------------
/glass/CodeCompressor/__init__.py:
--------------------------------------------------------------------------------
1 | from .CodeCompressor import CodeCompressor
2 |
--------------------------------------------------------------------------------
/glass/CodeCompressor/pcpp/LICENSE:
--------------------------------------------------------------------------------
1 | (C) 2018-2019 Niall Douglas http://www.nedproductions.biz/
2 | and (C) 2007-2019 David Beazley http://www.dabeaz.com/
3 |
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are
8 | met:
9 |
10 | * Redistributions of source code must retain the above copyright notice,
11 | this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 | * Neither the name of the David Beazley or Dabeaz LLC may be used to
16 | endorse or promote products derived from this software without
17 | specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/glass/CodeCompressor/pcpp/__init__.py:
--------------------------------------------------------------------------------
1 | from .evaluator import Evaluator
2 | from .parser import Action, OutputDirective
3 | from .pcmd import main, version, CmdPreprocessor
4 | from .preprocessor import Preprocessor
5 |
6 | __version__ = version
7 |
--------------------------------------------------------------------------------
/glass/CodeCompressor/pcpp/ply/__init__.py:
--------------------------------------------------------------------------------
1 | # PLY package
2 | # Author: David Beazley (dave@dabeaz.com)
3 |
4 | __version__ = "3.11"
5 | __all__ = ["lex", "yacc"]
6 |
--------------------------------------------------------------------------------
/glass/CustomLiteral.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Tuple, Type, Union
2 |
3 |
4 | class _CustomLiteralMeta(type):
5 |
6 | def __getitem__(cls, args: Union[Tuple[Any, ...], Any]) -> Type:
7 | if not isinstance(args, tuple):
8 | args = (args,)
9 | name = f"CustomLiteral[{', '.join(map(repr, args))}]"
10 | new_cls = type.__new__(_CustomLiteralMeta, name, (), {"__args__": args})
11 | return new_cls
12 |
13 | def __instancecheck__(cls, instance: Any) -> bool:
14 | return any(instance == arg for arg in getattr(cls, "__args__", ()))
15 |
16 | def __contains__(cls, item: Any)->bool:
17 | return (item in cls.__args__)
18 |
19 | class CustomLiteral(metaclass=_CustomLiteralMeta):
20 |
21 | def __class_getitem__(cls, args) -> Type:
22 | return _CustomLiteralMeta.__getitem__(cls, args)
--------------------------------------------------------------------------------
/glass/EBO.py:
--------------------------------------------------------------------------------
1 | from .BO import BO
2 |
3 | from OpenGL import GL
4 |
5 |
6 | class EBO(BO):
7 |
8 | _basic_info = {
9 | "gen_func": GL.glGenBuffers,
10 | "bind_func": GL.glBindBuffer,
11 | "del_func": GL.glDeleteBuffers,
12 | "target_type": GL.GL_ELEMENT_ARRAY_BUFFER,
13 | "binding_type": GL.GL_ELEMENT_ARRAY_BUFFER_BINDING,
14 | "need_number": True,
15 | }
16 |
17 | def __init__(self):
18 | BO.__init__(self)
19 |
--------------------------------------------------------------------------------
/glass/GlassConfig.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 | import re
4 |
5 | from .GLConfig import GLConfig
6 |
7 |
8 | class GlassConfig:
9 |
10 | def __init__(self):
11 | self_folder = os.path.dirname(os.path.abspath(__file__)).replace("\\", "/")
12 | glass_engine_glsl_folder = os.path.abspath(
13 | self_folder + "/../glass_engine/glsl"
14 | ).replace("\\", "/")
15 | glass_glsl_folder = self_folder + "/glsl"
16 | if os.path.isdir(glass_engine_glsl_folder):
17 | self.__cache_folder = glass_engine_glsl_folder + "/__glcache__"
18 | else:
19 | self.__cache_folder = glass_glsl_folder + "/__glcache__"
20 |
21 | self.debug: bool = False
22 | self.print: bool = True
23 | self.warning: bool = True
24 | self.recompile: bool = False
25 | self.save_used_shaders: bool = False
26 |
27 | @property
28 | def cache_folder(self) -> str:
29 | if not os.path.isdir(self.__cache_folder):
30 | os.makedirs(self.__cache_folder)
31 |
32 | return self.__cache_folder
33 |
34 | @cache_folder.setter
35 | def cache_folder(self, folder_path: str):
36 | self.__cache_folder = folder_path
37 |
38 | @property
39 | def renderer_folder(self) -> str:
40 | santified_renderer = re.sub(r'[\\/:*?"<>|]', " ", GLConfig.renderer)
41 | renderer_folder = f"{self.__cache_folder}/{santified_renderer}"
42 | if not os.path.isdir(renderer_folder):
43 | os.makedirs(renderer_folder)
44 |
45 | return renderer_folder
46 |
47 | def clear_cache(self):
48 | if os.path.isdir(self.__cache_folder):
49 | shutil.rmtree(self.__cache_folder)
50 |
51 |
52 | GlassConfig = GlassConfig()
53 |
--------------------------------------------------------------------------------
/glass/ImageUnits.py:
--------------------------------------------------------------------------------
1 | from .GLConfig import GLConfig
2 |
3 |
4 | class ImageUnits:
5 | def __init__(self):
6 | self._unit_image_map = {}
7 | self._image_unit_map = {}
8 |
9 | def __getitem__(self, unit: int) -> tuple:
10 | key = (GLConfig.buffered_current_context, unit)
11 | if key not in self._unit_image_map:
12 | return None
13 |
14 | return self._unit_image_map[key]
15 |
16 | def __setitem__(self, unit: int, image: tuple):
17 | context = GLConfig.buffered_current_context
18 |
19 | unit_key = (context, unit)
20 | if unit_key in self._unit_image_map:
21 | old_image = self._unit_image_map[unit_key]
22 | if old_image != image:
23 | del self._image_unit_map[context, old_image]
24 |
25 | image_key = (context, image)
26 | if image_key in self._image_unit_map:
27 | old_unit = self._image_unit_map[image_key]
28 | if old_unit != unit:
29 | del self._unit_image_map[context, old_unit]
30 |
31 | self._unit_image_map[unit_key] = image
32 | self._image_unit_map[image_key] = unit
33 |
34 | def unit_of_image(self, image: tuple) -> int:
35 | key = (GLConfig.buffered_current_context, image)
36 | if key not in self._image_unit_map:
37 | return None
38 |
39 | return self._image_unit_map[key]
40 |
41 | @property
42 | def available_unit(self):
43 | context = GLConfig.buffered_current_context
44 |
45 | for i in range(GLConfig.max_image_units):
46 | key = (context, i)
47 | if key not in self._unit_image_map:
48 | return i
49 |
50 | if self._unit_image_map[key] == 0:
51 | return i
52 |
53 | return None
54 |
55 |
56 | ImageUnits = ImageUnits()
57 |
--------------------------------------------------------------------------------
/glass/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023-2025 王炳辉 (binghui.wang@foxmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/glass/MetaInstancesRecorder.py:
--------------------------------------------------------------------------------
1 | from .WeakSet import WeakSet
2 | import functools
3 |
4 |
5 | class MetaInstancesRecorder(type):
6 |
7 | _all_instances = {}
8 |
9 | @property
10 | def all_instances(cls):
11 | all_instances = WeakSet()
12 | for key, _set in MetaInstancesRecorder._all_instances.items():
13 | if issubclass(key, cls):
14 | all_instances.update(_set)
15 |
16 | return all_instances
17 |
18 | def init(func):
19 |
20 | @functools.wraps(func)
21 | def wrapper(*args, **kwargs):
22 | self = args[0]
23 | if self.__class__ not in MetaInstancesRecorder._all_instances:
24 | MetaInstancesRecorder._all_instances[self.__class__] = WeakSet()
25 |
26 | MetaInstancesRecorder._all_instances[self.__class__].add(self)
27 | return func(*args, **kwargs)
28 |
29 | return wrapper
30 |
31 | def delete(func):
32 |
33 | @functools.wraps(func)
34 | def wrapper(*args, **kwargs):
35 | self = args[0]
36 | if self.__class__ in MetaInstancesRecorder._all_instances:
37 | MetaInstancesRecorder._all_instances[self.__class__].remove(self)
38 |
39 | return func(*args, **kwargs)
40 |
41 | return wrapper
42 |
--------------------------------------------------------------------------------
/glass/README_PYPI.md:
--------------------------------------------------------------------------------
1 | # Glass -- 为 Glass Engine 提供 OpenGL 易用封装
2 |
3 | **Glass** 为 **Glass Engine** 的子项目,为 OpenGL Assistant 的缩写。
4 | OpenGL 函数的底层接口的设计为了跨平台,牺牲了易用性。
5 | 为了使 OpenGL 的调用对 Python 用户更友好,封装了 **Glass** 库。
6 | 该库简化了大量 OpenGL 概念以及函数调用方法,几项重点简化包括:
7 |
8 | * 支持从文件编译 Shader,支持在 Shader 中使用 ``include``,并将报错行号指向真实的 include 文件;
9 | * ShaderProgram 自动采用增量编译策略,仅当文件和依赖改变时重新编译;
10 | * 设置 Uniform/Uniform Block/Shader Storage Block 变量时,Python 对象可直接赋值给 Shader 中的对应结构变量;
11 | * 提供 Vertices/Indices 类对顶点和索引进行管理,用户无需接触 VBO/VAO/EBO 等直接操作显存的概念;
12 | * 变化的顶点和索引采用增量拷贝算法同步到显存,提高拷贝效率。
13 |
14 | 下面是一段不完整的代码展示了 glass 操作 OpenGL 的方法:
15 |
16 | ```python
17 | from glass import *
18 |
19 | # 在一个合法的 OpenGL 上下文中:
20 |
21 | # 创建 shader 程序
22 | program = ShaderProgram()
23 | program.compile("path/to/vertex_shader.vert")
24 | program.compile("path/to/fragment_shader.frag")
25 | # 上述两个 compile 并不会每次运行都编译,仅首次以及 Shader 文件修改后才编译
26 | # shader 文件中可含有 #include 语法
27 |
28 | # 将 Python 变量 pyvar 直接赋值给 Shader 端的 Uniform 结构体变量 uniform_var
29 | # 只要 Python 变量中含有对应的属性
30 | program["uniform_var"] = pyvar
31 |
32 | # 纹理 uniform 变量可用如下方法赋值
33 | # 对用户隐藏纹理单元概念
34 | program["sampler_var"] = sampler2D("path/to/image.png")
35 |
36 | # 创建顶点数组
37 | vertices = Vertices() # 像 list 一样操作 vertices,只不过元素只能为 Vertex 类型
38 |
39 | # 添加顶点
40 | vertices.append(Vertex(position=glm.vec2(-0.5,-0.5), color=glm.vec3(1,0,0)))
41 | vertices.append(Vertex(position=glm.vec2(0.5,-0.5), color=glm.vec3(0,1,0)))
42 | vertices.append(Vertex(position=glm.vec2(0,0.5), color=glm.vec3(0,0,1)))
43 | # 构建顶点 Vertex 时,属性名可为任意值
44 | # 只要在 vertex shader 中的 layout 指定了该属性名并且类型匹配
45 |
46 | # 创建索引数组
47 | indices = Indices() # 像 list 一样操作 indices,只不过元素只能为 glm.uvec3 类型
48 | indices.append(glm.uvec3(0, 1, 2))
49 |
50 | # 绘制三角形
51 | program.draw_triangles(vertices=vertices, indices=indices)
52 |
53 | # vertices 和 indices 可在任意时刻动态修改内部元素,以及动态增加删除元素
54 | # 所有修改将在下次绘制时同步到显存
55 | ```
56 |
57 | 你可以在任意需要使用 OpenGL 的地方使用 **Glass**,
58 | 但其初衷是为 **Glass Engine** 提供 OpenGL 的封装,因此不过多介绍 **Glass** 的用法,欢迎访问 **Glass Engine** 项目:
59 |
60 | * [文档](https://glass-engine-doc.readthedocs.io/zh/latest/)
61 | * [Github 项目主页](https://github.com/Time-Coder/Glass-Engine)
62 | * [Gitee 项目主页](https://gitee.com/time-coder/Glass-Engine)
63 | * [PyPI 索引](https://pypi.org/project/glass-engine/)
64 |
--------------------------------------------------------------------------------
/glass/ShaderStorageBlock.py:
--------------------------------------------------------------------------------
1 | from .Block import Block
2 | from .SSBO import SSBO
3 |
4 |
5 | class ShaderStorageBlock(Block):
6 |
7 | BO = SSBO
8 |
9 | def __init__(self, program):
10 | Block.__init__(self, program)
11 |
--------------------------------------------------------------------------------
/glass/TextureUnits.py:
--------------------------------------------------------------------------------
1 | from .GLConfig import GLConfig
2 |
3 |
4 | class TextureUnits:
5 | def __init__(self):
6 | self._unit_texture_map = {}
7 | self._texture_unit_map = {}
8 |
9 | def __getitem__(self, unit: int) -> tuple:
10 | key = (GLConfig.buffered_current_context, unit)
11 | if key not in self._unit_texture_map:
12 | return None
13 |
14 | return self._unit_texture_map[key]
15 |
16 | def __setitem__(self, unit: int, texture: tuple):
17 | context = GLConfig.buffered_current_context
18 |
19 | unit_key = (context, unit)
20 | if unit_key in self._unit_texture_map:
21 | old_texture = self._unit_texture_map[unit_key]
22 | if old_texture != texture:
23 | del self._texture_unit_map[context, old_texture]
24 |
25 | texture_key = (context, texture)
26 | if texture_key in self._texture_unit_map:
27 | old_unit = self._texture_unit_map[texture_key]
28 | if old_unit != unit:
29 | del self._unit_texture_map[context, old_unit]
30 |
31 | self._unit_texture_map[unit_key] = texture
32 | self._texture_unit_map[texture_key] = unit
33 |
34 | @property
35 | def current_texture(self):
36 | return self[GLConfig.active_texture_unit]
37 |
38 | @current_texture.setter
39 | def current_texture(self, texture: tuple):
40 | self[GLConfig.active_texture_unit] = texture
41 |
42 | def unit_of_texture(self, texture: tuple) -> int:
43 | key = (GLConfig.buffered_current_context, texture)
44 | if key not in self._texture_unit_map:
45 | return None
46 |
47 | return self._texture_unit_map[key]
48 |
49 | @property
50 | def available_unit(self):
51 | context = GLConfig.buffered_current_context
52 |
53 | for i in range(GLConfig.max_texture_units):
54 | key = (context, i)
55 | if key not in self._unit_texture_map:
56 | return i
57 |
58 | if self._unit_texture_map[key] == 0:
59 | return i
60 |
61 | return None
62 |
63 |
64 | TextureUnits = TextureUnits()
65 |
--------------------------------------------------------------------------------
/glass/UBO.py:
--------------------------------------------------------------------------------
1 | from .SSUBO import SSUBO
2 |
3 | from OpenGL import GL
4 |
5 |
6 | class UBO(SSUBO):
7 |
8 | _basic_info = {
9 | "gen_func": GL.glGenBuffers,
10 | "bind_func": GL.glBindBuffer,
11 | "del_func": GL.glDeleteBuffers,
12 | "target_type": GL.GL_UNIFORM_BUFFER,
13 | "binding_type": GL.GL_UNIFORM_BUFFER_BINDING,
14 | "need_number": True,
15 | }
16 |
17 | _binding_points_pool = None
18 | _current_context = 0
19 |
20 | def __init__(self):
21 | SSUBO.__init__(self)
22 |
--------------------------------------------------------------------------------
/glass/UniformBlock.py:
--------------------------------------------------------------------------------
1 | from .Block import Block
2 | from .UBO import UBO
3 |
4 |
5 | class UniformBlock(Block):
6 |
7 | BO = UBO
8 |
9 | def __init__(self, shader_program):
10 | Block.__init__(self, shader_program)
11 |
--------------------------------------------------------------------------------
/glass/VBO.py:
--------------------------------------------------------------------------------
1 | from .BO import BO
2 |
3 | from OpenGL import GL
4 |
5 |
6 | class VBO(BO):
7 |
8 | _basic_info = {
9 | "gen_func": GL.glGenBuffers,
10 | "bind_func": GL.glBindBuffer,
11 | "del_func": GL.glDeleteBuffers,
12 | "target_type": GL.GL_ARRAY_BUFFER,
13 | "binding_type": GL.GL_ARRAY_BUFFER_BINDING,
14 | "need_number": True,
15 | }
16 |
17 | def __init__(self):
18 | BO.__init__(self)
19 | self._location = -1
20 |
--------------------------------------------------------------------------------
/glass/WeakList.py:
--------------------------------------------------------------------------------
1 | from .WeakRef import WeakRef
2 |
3 | from typing import Any, Iterable, Iterator, Union, List
4 |
5 |
6 | class WeakList:
7 |
8 | class iterator:
9 | def __init__(self, iterator: Iterator):
10 | self._iterator: Iterator = iterator
11 |
12 | def __next__(self) -> Any:
13 | return self._iterator.__next__().value
14 |
15 | def __iter__(self) -> Iterator:
16 | return self
17 |
18 | def __init__(self) -> None:
19 | self._list: List[WeakRef] = []
20 |
21 | def __setitem__(self, index: Union[int, slice], value: Any) -> None:
22 | self._list[index] = WeakRef(value)
23 |
24 | def __getitem__(self, index: Union[int, slice]) -> Any:
25 | value: Any = self._list[index]
26 | if isinstance(index, slice):
27 | return list(map(lambda x: x.value, value))
28 | else:
29 | return value.value
30 |
31 | def __delitem__(self, index: Union[int, slice]) -> None:
32 | del self._list[index]
33 |
34 | def __contains__(self, value: Any) -> bool:
35 | return WeakRef(value) in self._list
36 |
37 | def __len__(self) -> int:
38 | return self._list.__len__()
39 |
40 | def __bool__(self) -> bool:
41 | return bool(self._list)
42 |
43 | def __iter__(self) -> Iterator:
44 | return WeakList.iterator(self._list.__iter__())
45 |
46 | def append(self, value: Any) -> None:
47 | self._list.append(WeakRef(value))
48 |
49 | def insert(self, index: int, value: Any) -> None:
50 | self._list.insert(index, WeakRef(value))
51 |
52 | def extend(self, value_list: Iterable):
53 | if isinstance(value_list, WeakList):
54 | self._list.extend(value_list._list)
55 | else:
56 | self._list.extend(map(lambda x: WeakRef(x), value_list))
57 |
58 | def index(self, value: Any) -> int:
59 | return self._list.index(WeakRef(value))
60 |
61 | def remove(self, value: Any) -> None:
62 | self._list.remove(WeakRef(value))
63 |
64 | def pop(self, index: int) -> Any:
65 | return self._list.pop(index).value
66 |
67 | def clear(self) -> None:
68 | self._list.clear()
69 |
--------------------------------------------------------------------------------
/glass/WeakRef.py:
--------------------------------------------------------------------------------
1 | from .utils import di
2 |
3 | from typing import Any, Union
4 |
5 |
6 | class WeakRef:
7 |
8 | def __init__(self, obj: Any) -> None:
9 | if isinstance(obj, (int, float, complex, bool, str, bytes, type(None))):
10 | self._obj_id: Union[int, float, complex, bool, str, bytes, None] = obj
11 | self._is_real_id: bool = False
12 | else:
13 | self._obj_id: Union[int, float, complex, bool, str, bytes, None] = id(obj)
14 | self._is_real_id: bool = True
15 |
16 | def __hash__(self) -> int:
17 | return hash(self._obj_id)
18 |
19 | def __eq__(self, other: Any) -> bool:
20 | if isinstance(other, WeakRef):
21 | return self._obj_id == other._obj_id
22 | else:
23 | return self.value == other
24 |
25 | def __repr__(self) -> str:
26 | return self.value.__repr__()
27 |
28 | @property
29 | def value(self) -> Any:
30 | if self._is_real_id:
31 | return di(self._obj_id)
32 | else:
33 | return self._obj_id
34 |
--------------------------------------------------------------------------------
/glass/WeakSet.py:
--------------------------------------------------------------------------------
1 | from .WeakRef import WeakRef
2 |
3 |
4 | class WeakSet:
5 |
6 | class iterator:
7 | def __init__(self, _iterator):
8 | self._iterator = _iterator
9 |
10 | def __next__(self):
11 | value = self._iterator.__next__()
12 | return value.value
13 |
14 | def __iter__(self):
15 | return self
16 |
17 | def __init__(self):
18 | self._set = set()
19 |
20 | def __iter__(self):
21 | result = WeakSet.iterator(self._set.__iter__())
22 | return result
23 |
24 | def __len__(self):
25 | return len(self._set)
26 |
27 | def __bool__(self):
28 | return bool(self._set)
29 |
30 | def __contains__(self, value):
31 | return WeakRef(value) in self._set
32 |
33 | def __repr__(self):
34 | return self._set.__repr__()
35 |
36 | def __sub__(self, other):
37 | result = WeakSet()
38 | if isinstance(other, WeakSet):
39 | result._set = self._set - other._set
40 | else:
41 | result._set = self._set - map(lambda x: WeakRef(x), other)
42 |
43 | return result
44 |
45 | def __add__(self, other):
46 | result = WeakSet()
47 | if isinstance(other, WeakSet):
48 | result._set = self._set + other._set
49 | else:
50 | result._set = self._set + map(lambda x: WeakRef(x), other)
51 |
52 | return result
53 |
54 | def __isub__(self, other):
55 | result = WeakSet()
56 | if isinstance(other, WeakSet):
57 | self._set -= other._set
58 | else:
59 | self._set -= map(lambda x: WeakRef(x), other)
60 |
61 | return result
62 |
63 | def __iadd__(self, other):
64 | result = WeakSet()
65 | if isinstance(other, WeakSet):
66 | self._set += other._set
67 | else:
68 | self._set += map(lambda x: WeakRef(x), other)
69 |
70 | return result
71 |
72 | def add(self, value):
73 | self._set.add(WeakRef(value))
74 |
75 | def remove(self, value):
76 | ref_value = WeakRef(value)
77 | if ref_value in self._set:
78 | self._set.remove(ref_value)
79 |
80 | def pop(self):
81 | return self._set.pop().value
82 |
83 | def clear(self):
84 | self._set.clear()
85 |
86 | def update(self, new_set):
87 | if isinstance(new_set, WeakSet):
88 | self._set.update(new_set._set)
89 | else:
90 | self._set.update(map(lambda x: WeakRef(x), new_set))
91 |
--------------------------------------------------------------------------------
/glass/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "0.1.64"
2 |
3 | from .VAO import VAO
4 | from .VBO import VBO
5 | from .EBO import EBO
6 | from .FBO import FBO
7 | from .RBO import RBO
8 | from .SSBO import SSBO
9 | from .UBO import UBO
10 | from .ACBO import ACBO
11 |
12 | from .sampler2D import sampler2D
13 | from .usampler2D import usampler2D
14 | from .isampler2D import isampler2D
15 | from .image2D import image2D
16 | from .uimage2D import uimage2D
17 | from .iimage2D import iimage2D
18 | from .sampler2DMS import sampler2DMS
19 | from .isampler2DMS import isampler2DMS
20 | from .usampler2DMS import usampler2DMS
21 | from .samplerCube import samplerCube
22 | from .sampler2DArray import sampler2DArray
23 |
24 | from .Vertices import Vertices, Vertex
25 | from .Indices import Indices
26 | from .Instances import Instance, Instances
27 | from .AttrList import AttrList
28 |
29 | from .ShaderProgram import ShaderProgram
30 | from .ComputeProgram import ComputeProgram
31 |
32 | from .ShaderStorageBlock import ShaderStorageBlock
33 | from .UniformBlock import UniformBlock
34 | from .Block import Block
35 | from .Uniform import Uniform
36 |
37 | from .GLConfig import GLConfig
38 | from .GlassConfig import GlassConfig
39 | from .GLInfo import GLInfo
40 | from .RenderHints import RenderHints
41 | from .download import download
42 | from .ImageLoader import ImageLoader
43 |
44 | # from .TextLoader import TextLoader, Font
45 | from .CustomLiteral import CustomLiteral
46 | from .callback_vec import callback_vec2, callback_vec3, callback_vec4, callback_quat
--------------------------------------------------------------------------------
/glass/__pyinstaller/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | def get_hook_dirs():
5 | return [os.path.dirname(os.path.abspath(__file__)).replace("\\", "/")]
6 |
--------------------------------------------------------------------------------
/glass/__pyinstaller/hook-glass.py:
--------------------------------------------------------------------------------
1 | import os
2 | import platform
3 |
4 |
5 | def find_files(directory):
6 | file_list = []
7 | abs_directory = (
8 | os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/..").replace(
9 | "\\", "/"
10 | )
11 | + "/"
12 | + directory
13 | )
14 | for root, _, files in os.walk(abs_directory):
15 | for file in files:
16 | file_path = os.path.abspath(os.path.join(root, file)).replace("\\", "/")
17 | if not os.path.isfile(file_path):
18 | continue
19 |
20 | target_path = (
21 | "glass/"
22 | + directory
23 | + file_path[
24 | len(abs_directory) : (-len(os.path.basename(file_path)) - 1)
25 | ]
26 | )
27 | if "__glcache__" not in file_path:
28 | file_list.append((file_path.replace("\\", "/"), target_path))
29 | return file_list
30 |
31 | self_folder = os.path.dirname(os.path.abspath(__file__))
32 | datas = find_files("glsl")
33 | datas.extend(
34 | [
35 | (
36 | os.path.abspath(self_folder + "/../LICENSE").replace("\\", "/"),
37 | "glass",
38 | ),
39 | (
40 | os.path.abspath(self_folder + "/../CodeCompressor/pcpp/LICENSE").replace("\\", "/"),
41 | "glass/CodeCompressor/pcpp",
42 | )
43 | ]
44 | )
45 | if platform.system() == "Linux":
46 | hiddenimports = ["OpenGL.platform.egl"]
47 |
--------------------------------------------------------------------------------
/glass/glsl/draw_frame.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | out vec2 tex_coord;
4 |
5 | void main()
6 | {
7 | switch (gl_VertexID)
8 | {
9 | case 0:
10 | case 5:
11 | {
12 | gl_Position = vec4(-1, -1, 0.0, 1.0);
13 | tex_coord = vec2(0, 0);
14 | break;
15 | }
16 |
17 | case 1:
18 | {
19 | gl_Position = vec4(1, -1, 0.0, 1.0);
20 | tex_coord = vec2(1, 0);
21 | break;
22 | }
23 |
24 | case 2:
25 | case 3:
26 | {
27 | gl_Position = vec4(1, 1, 0.0, 1.0);
28 | tex_coord = vec2(1, 1);
29 | break;
30 | }
31 |
32 | case 4:
33 | {
34 | gl_Position = vec4(-1, 1, 0.0, 1.0);
35 | tex_coord = vec2(0, 1);
36 | break;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/glass/glsl/shadertoy_template.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 out_color;
5 |
6 | uniform vec3 iResolution; // viewport resolution (in pixels)
7 | uniform float iTime; // shader playback time (in seconds)
8 | uniform float iTimeDelta; // render time (in seconds)
9 | uniform float iFrameRate; // shader frame rate
10 | uniform int iFrame; // shader playback frame
11 | uniform float iChannelTime[4]; // channel playback time (in seconds)
12 | uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
13 | uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
14 | uniform sampler2D iChannel0, iChannel1, iChannel2, iChannel3; // input channel. XX = 2D/Cube
15 | uniform vec4 iDate; // (year, month, day, time in seconds)
16 | uniform float iSampleRate; // sound sample rate (i.e., 44100)
17 |
18 | #include FILE_NAME
19 |
20 | void main()
21 | {
22 | vec2 frag_coord = tex_coord * iResolution.xy;
23 | mainImage(out_color, frag_coord);
24 | }
--------------------------------------------------------------------------------
/glass/iimage2D.py:
--------------------------------------------------------------------------------
1 | from .sampler2D import sampler2D
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 | from .isampler2D import isampler2D
5 |
6 | from OpenGL import GL
7 | import numpy as np
8 | from typing import Union
9 |
10 |
11 | class iimage2D(isampler2D):
12 |
13 | _default_internal_format = GL.GL_RGBA32I
14 | _default_filter_min = GL.GL_NEAREST
15 | _default_filter_mag = GL.GL_NEAREST
16 | _default_filter_mipmap = None
17 |
18 | @checktype
19 | def __init__(
20 | self,
21 | image: Union[str, np.ndarray, None] = None,
22 | width: int = None,
23 | height: int = None,
24 | internal_format: GLInfo.iimage_internal_formats = None,
25 | ):
26 | isampler2D.__init__(self, image, width, height, internal_format)
27 |
28 | @property
29 | def internal_format(self):
30 | return self._internal_format
31 |
32 | @internal_format.setter
33 | @sampler2D.param_setter
34 | def internal_format(self, internal_format: GLInfo.iimage_internal_formats):
35 | self._set_internal_format(internal_format)
36 |
37 | @property
38 | def filter_min(self):
39 | return GL.GL_NEAREST
40 |
41 | @filter_min.setter
42 | def filter_min(self, filter_type: GLInfo.filter_types):
43 | raise RuntimeError("cannot set filter for iimage2D")
44 |
45 | @property
46 | def filter_mag(self):
47 | return GL.GL_NEAREST
48 |
49 | @filter_mag.setter
50 | def filter_mag(self, filter_type: GLInfo.filter_types):
51 | raise RuntimeError("cannot set filter for iimage2D")
52 |
53 | @property
54 | def filter_mipmap(self):
55 | return GL.GL_NONE
56 |
57 | @filter_mipmap.setter
58 | def filter_mipmap(self, filter_type: GLInfo.filter_types):
59 | raise RuntimeError("cannot set filter for iimage2D")
60 |
61 | @property
62 | def filter(self):
63 | return GL.GL_NEAREST, GL.GL_NEAREST, None
64 |
65 | @filter.setter
66 | def filter(self, filter_type):
67 | raise RuntimeError("cannot set filter for iimage2D")
68 |
--------------------------------------------------------------------------------
/glass/image2D.py:
--------------------------------------------------------------------------------
1 | from OpenGL import GL
2 | import numpy as np
3 | from typing import Union
4 |
5 | from .FBOAttachment import FBOAttachment
6 | from .GLInfo import GLInfo
7 | from .utils import checktype
8 | from .sampler2D import sampler2D
9 |
10 |
11 | class image2D(sampler2D):
12 |
13 | _default_internal_format = GL.GL_RGBA32F
14 | _default_filter_min = GL.GL_NEAREST
15 | _default_filter_mag = GL.GL_NEAREST
16 | _default_filter_mipmap = None
17 |
18 | @checktype
19 | def __init__(
20 | self,
21 | image: Union[str, np.ndarray] = None,
22 | width: int = None,
23 | height: int = None,
24 | internal_format: GLInfo.image_internal_formats = None,
25 | ):
26 | sampler2D.__init__(self, image, width, height, internal_format)
27 |
28 | @property
29 | def internal_format(self):
30 | return self._internal_format
31 |
32 | @internal_format.setter
33 | @FBOAttachment.param_setter
34 | def internal_format(self, internal_format: GLInfo.image_internal_formats):
35 | self._set_internal_format(internal_format)
36 |
37 | @property
38 | def filter_min(self):
39 | return GL.GL_NEAREST
40 |
41 | @filter_min.setter
42 | def filter_min(self, filter_type: GLInfo.filter_types):
43 | raise RuntimeError("cannot set filter for image2D")
44 |
45 | @property
46 | def filter_mag(self):
47 | return GL.GL_NEAREST
48 |
49 | @filter_mag.setter
50 | def filter_mag(self, filter_type: GLInfo.filter_types):
51 | raise RuntimeError("cannot set filter for image2D")
52 |
53 | @property
54 | def filter_mipmap(self):
55 | return GL.GL_NONE
56 |
57 | @filter_mipmap.setter
58 | def filter_mipmap(self, filter_type: GLInfo.filter_types):
59 | raise RuntimeError("cannot set filter for image2D")
60 |
61 | @property
62 | def filter(self):
63 | return GL.GL_NEAREST, GL.GL_NEAREST, None
64 |
65 | @filter.setter
66 | def filter(self, filter_type):
67 | raise RuntimeError("cannot set filter for image2D")
68 |
--------------------------------------------------------------------------------
/glass/isampler2D.py:
--------------------------------------------------------------------------------
1 | from .sampler2D import sampler2D
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 |
5 | from OpenGL import GL
6 | import OpenGL.GL.ARB.bindless_texture as bt
7 | import numpy as np
8 | from typing import Union
9 |
10 |
11 | class isampler2D(sampler2D):
12 |
13 | _default_internal_format = GL.GL_RGBA32I
14 | _default_filter_min = GL.GL_NEAREST
15 | _default_filter_mag = GL.GL_NEAREST
16 | _default_filter_mipmap = None
17 |
18 | @checktype
19 | def __init__(
20 | self,
21 | image: Union[str, np.ndarray] = None,
22 | width: int = None,
23 | height: int = None,
24 | internal_format: GLInfo.isampler_internal_formats = None,
25 | ):
26 | if internal_format is None:
27 | internal_format = GL.GL_RGBA32I
28 |
29 | sampler2D.__init__(self, image, width, height, internal_format)
30 |
31 | @property
32 | def internal_format(self):
33 | return self._internal_format
34 |
35 | @internal_format.setter
36 | @sampler2D.param_setter
37 | def internal_format(self, internal_format: GLInfo.isampler_internal_formats):
38 | self._set_internal_format(internal_format)
39 |
40 | @property
41 | def handle(self):
42 | if not bt.glGetTextureHandleARB:
43 | return 0
44 |
45 | self.bind()
46 | if self._handle == 0:
47 | self._handle = bt.glGetTextureHandleARB(self._id)
48 | if self._handle == 0:
49 | raise RuntimeError(f"failed to create isampler2D {self._id}'s handle")
50 | bt.glMakeTextureHandleResidentARB(self._handle)
51 |
52 | self._dynamic = False
53 |
54 | return self._handle
55 |
--------------------------------------------------------------------------------
/glass/isampler2DMS.py:
--------------------------------------------------------------------------------
1 | from .sampler2DMS import sampler2DMS
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 |
5 | from OpenGL import GL
6 | import OpenGL.GL.ARB.bindless_texture as bt
7 |
8 |
9 | class isampler2DMS(sampler2DMS):
10 |
11 | @checktype
12 | def __init__(
13 | self,
14 | width: int = 0,
15 | height: int = 0,
16 | samples: int = 4,
17 | internal_format: GLInfo.isampler_internal_formats = None,
18 | ):
19 | if internal_format is None:
20 | internal_format = GL.GL_RGBA32I
21 |
22 | sampler2DMS.__init__(self, width, height, samples, internal_format)
23 |
24 | @property
25 | def internal_format(self):
26 | return self._internal_format
27 |
28 | @internal_format.setter
29 | @checktype
30 | def internal_format(self, format: GLInfo.isampler_internal_formats):
31 | if self._internal_format != format:
32 | self._internal_format = format
33 | self._param_changed = True
34 |
35 | @property
36 | def handle(self):
37 | if not bt.glGetTextureHandleARB:
38 | return 0
39 |
40 | self.bind()
41 | if self._handle == 0:
42 | self._handle = bt.glGetTextureHandleARB(self._id)
43 | if self._handle == 0:
44 | raise RuntimeError(f"failed to create isampler2D {self._id}'s handle")
45 | bt.glMakeTextureHandleResidentARB(self._handle)
46 | self._dynamic = False
47 |
48 | return self._handle
49 |
--------------------------------------------------------------------------------
/glass/uimage2D.py:
--------------------------------------------------------------------------------
1 | from .sampler2D import sampler2D
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 | from .usampler2D import usampler2D
5 |
6 | from OpenGL import GL
7 | import numpy as np
8 | from typing import Union
9 |
10 |
11 | class uimage2D(usampler2D):
12 |
13 | _default_internal_format = GL.GL_RGBA32UI
14 | _default_filter_min = GL.GL_NEAREST
15 | _default_filter_mag = GL.GL_NEAREST
16 | _default_filter_mipmap = None
17 |
18 | @checktype
19 | def __init__(
20 | self,
21 | image: Union[str, np.ndarray] = None,
22 | width: int = None,
23 | height: int = None,
24 | internal_format: GLInfo.uimage_internal_formats = None,
25 | ):
26 | usampler2D.__init__(self, image, width, height, internal_format)
27 |
28 | @property
29 | def internal_format(self):
30 | return self._internal_format
31 |
32 | @internal_format.setter
33 | @sampler2D.param_setter
34 | def internal_format(self, internal_format: GLInfo.uimage_internal_formats):
35 | self._set_internal_format(internal_format)
36 |
37 | @property
38 | def filter_min(self):
39 | return GL.GL_NEAREST
40 |
41 | @filter_min.setter
42 | def filter_min(self, filter_type: GLInfo.filter_types):
43 | raise RuntimeError("cannot set filter for uimage2D")
44 |
45 | @property
46 | def filter_mag(self):
47 | return GL.GL_NEAREST
48 |
49 | @filter_mag.setter
50 | def filter_mag(self, filter_type: GLInfo.filter_types):
51 | raise RuntimeError("cannot set filter for uimage2D")
52 |
53 | @property
54 | def filter_mipmap(self):
55 | return GL.GL_NONE
56 |
57 | @filter_mipmap.setter
58 | def filter_mipmap(self, filter_type: GLInfo.filter_types):
59 | raise RuntimeError("cannot set filter for uimage2D")
60 |
61 | @property
62 | def filter(self):
63 | return GL.GL_NEAREST, GL.GL_NEAREST, None
64 |
65 | @filter.setter
66 | def filter(self, filter_type):
67 | raise RuntimeError("cannot set filter for uimage2D")
68 |
--------------------------------------------------------------------------------
/glass/usampler2D.py:
--------------------------------------------------------------------------------
1 | from .sampler2D import sampler2D
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 |
5 | from OpenGL import GL
6 | import OpenGL.GL.ARB.bindless_texture as bt
7 | import numpy as np
8 | from typing import Union
9 |
10 |
11 | class usampler2D(sampler2D):
12 |
13 | _default_internal_format = GL.GL_RGBA32UI
14 | _default_filter_min = GL.GL_NEAREST
15 | _default_filter_mag = GL.GL_NEAREST
16 | _default_filter_mipmap = None
17 |
18 | @checktype
19 | def __init__(
20 | self,
21 | image: Union[str, np.ndarray] = None,
22 | width: int = None,
23 | height: int = None,
24 | internal_format: GLInfo.usampler_internal_formats = None,
25 | ):
26 | if internal_format is None:
27 | internal_format = GL.GL_RGBA32UI
28 |
29 | sampler2D.__init__(self, image, width, height, internal_format)
30 |
31 | @property
32 | def internal_format(self):
33 | return self._internal_format
34 |
35 | @internal_format.setter
36 | @sampler2D.param_setter
37 | def internal_format(self, internal_format: GLInfo.usampler_internal_formats):
38 | self._set_internal_format(internal_format)
39 |
40 | @property
41 | def handle(self):
42 | if not bt.glGetTextureHandleARB:
43 | return 0
44 |
45 | self.bind()
46 | if self._handle == 0:
47 | self._handle = bt.glGetTextureHandleARB(self._id)
48 | if self._handle == 0:
49 | raise RuntimeError(f"failed to create usampler2D {self._id}'s handle")
50 | bt.glMakeTextureHandleResidentARB(self._handle)
51 | self._dynamic = False
52 |
53 | return self._handle
54 |
--------------------------------------------------------------------------------
/glass/usampler2DMS.py:
--------------------------------------------------------------------------------
1 | from .sampler2DMS import sampler2DMS
2 | from .GLInfo import GLInfo
3 | from .utils import checktype
4 |
5 | from OpenGL import GL
6 | import OpenGL.GL.ARB.bindless_texture as bt
7 |
8 |
9 | class usampler2DMS(sampler2DMS):
10 |
11 | @checktype
12 | def __init__(
13 | self,
14 | width: int = 0,
15 | height: int = 0,
16 | samples: int = 4,
17 | internal_format: GLInfo.usampler_internal_formats = None,
18 | ):
19 | if internal_format is None:
20 | internal_format = GL.GL_RGBA32UI
21 |
22 | sampler2DMS.__init__(self, width, height, samples, internal_format)
23 |
24 | @property
25 | def internal_format(self):
26 | return self._internal_format
27 |
28 | @internal_format.setter
29 | @checktype
30 | def internal_format(self, format: GLInfo.usampler_internal_formats):
31 | if self._internal_format != format:
32 | self._internal_format = format
33 | self._param_changed = True
34 |
35 | @property
36 | def handle(self):
37 | if not bt.glGetTextureHandleARB:
38 | return 0
39 |
40 | self.bind()
41 | if self._handle == 0:
42 | self._handle = bt.glGetTextureHandleARB(self._id)
43 | if self._handle == 0:
44 | raise RuntimeError(f"failed to create isampler2D {self._id}'s handle")
45 | bt.glMakeTextureHandleResidentARB(self._handle)
46 | self._dynamic = False
47 |
48 | return self._handle
49 |
--------------------------------------------------------------------------------
/glass_engine/AffineTransform.py:
--------------------------------------------------------------------------------
1 | import glm
2 | from glass import Instance
3 |
4 |
5 | class AffineTransform(Instance):
6 | def __init__(self):
7 | Instance.__init__(self)
8 |
9 | self["affine_transform_row0"] = glm.vec4(1, 0, 0, 0)
10 | self["affine_transform_row1"] = glm.vec4(0, 1, 0, 0)
11 | self["affine_transform_row2"] = glm.vec4(0, 0, 1, 0)
12 | self["env_map_handle"] = 0
13 | self["visible"] = 1
14 |
15 | def apply(self, pos):
16 | transform_mat = glm.mat4(
17 | self["affine_transform_row0"],
18 | self["affine_transform_row1"],
19 | self["affine_transform_row2"],
20 | glm.vec4(0, 0, 0, 1),
21 | )
22 | transform_mat = glm.transpose(transform_mat)
23 | result = transform_mat * glm.vec4(*pos, 1)
24 | return result.xyz
25 |
--------------------------------------------------------------------------------
/glass_engine/Animations/AnimationGroup.py:
--------------------------------------------------------------------------------
1 | from .Animation import Animation
2 | from glass.DictList import DictList, ExtendableList
3 |
4 | from typing import Any
5 |
6 |
7 | def before_animation_add_callback(self: ExtendableList, animation: Any):
8 | if not isinstance(animation, Animation):
9 | raise TypeError("item add to AnimationGroup must be in type 'Animation'")
10 |
11 |
12 | def after_animation_add_callback(self: ExtendableList, animation: Any):
13 | animation._parents.add(self)
14 |
15 |
16 | def after_animation_remove_callback(self: ExtendableList, animation: Any):
17 | animation._parents.remove(self)
18 |
19 |
20 | class AnimationGroup(Animation, DictList):
21 |
22 | def __init__(self, *animations, **kwargs):
23 | Animation.__init__(self, **kwargs)
24 | DictList.__init__(
25 | self,
26 | values=animations,
27 | before_item_add_callback=before_animation_add_callback,
28 | after_item_add_callback=after_animation_add_callback,
29 | after_item_remove_callback=after_animation_remove_callback,
30 | )
31 |
32 | def _update_duration(self):
33 | return
34 |
35 | @property
36 | def duration(self):
37 | self._update_duration()
38 | return self._duration
39 |
40 | @property
41 | def total_duration(self):
42 | self._update_duration()
43 | return self._total_duration
44 |
--------------------------------------------------------------------------------
/glass_engine/Animations/EasingCurve.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 | import pytweening
3 |
4 |
5 | class EasingCurve(Enum):
6 |
7 | Linear = 0
8 | InQuad = 1
9 | OutQuad = 2
10 | InOutQuad = 3
11 | OutInQuad = 4
12 | InCubic = 5
13 | OutCubic = 6
14 | InOutCubic = 7
15 | OutInCubic = 8
16 | InQuart = 9
17 | OutQuart = 10
18 | InOutQuart = 11
19 | OutInQuart = 12
20 | InQuint = 13
21 | OutQuint = 14
22 | InOutQuint = 15
23 | OutInQuint = 16
24 | InSine = 17
25 | OutSine = 18
26 | InOutSine = 19
27 | OutInSine = 20
28 | InExpo = 21
29 | OutExpo = 22
30 | InOutExpo = 23
31 | OutInExpo = 24
32 | InCirc = 25
33 | OutCirc = 26
34 | InOutCirc = 27
35 | OutInCirc = 28
36 | InElastic = 29
37 | OutElastic = 30
38 | InOutElastic = 31
39 | OutInElastic = 32
40 | InBack = 33
41 | OutBack = 34
42 | InOutBack = 35
43 | OutInBack = 36
44 | InBounce = 37
45 | OutBounce = 38
46 | InOutBounce = 39
47 | OutInBounce = 40
48 |
49 | def __call__(self, progress: float) -> float:
50 | if self == EasingCurve.Linear:
51 | return progress
52 |
53 | func_name = "ease" + str(self)[len("EasingCurve.") :]
54 | func = getattr(pytweening, func_name)
55 | return func(progress)
56 |
--------------------------------------------------------------------------------
/glass_engine/Animations/ParallelAnimation.py:
--------------------------------------------------------------------------------
1 | from .AnimationGroup import AnimationGroup
2 |
3 |
4 | class ParallelAnimation(AnimationGroup):
5 |
6 | def __init__(self, *animations, **kwargs):
7 | AnimationGroup.__init__(self, *animations, **kwargs)
8 |
9 | def _update_duration(self):
10 | if not self._total_duration_dirty:
11 | return
12 |
13 | self._duration = 0
14 | for animation in self:
15 | if animation.total_duration > self._duration:
16 | self._duration = animation.total_duration
17 |
18 | self._total_duration = self._duration * self.loops
19 | if self._go_back:
20 | self._total_duration *= 2
21 |
22 | self._total_duration_dirty = False
23 |
24 | def _go_to(self, t: float):
25 | if t > self.total_duration:
26 | t = self.total_duration
27 | self._running = False
28 |
29 | progress = t / self.duration
30 | int_progress = int(progress)
31 | if progress != int_progress:
32 | progress -= int_progress
33 | elif progress != 0:
34 | progress = 1
35 | else:
36 | progress = 0
37 |
38 | if self.go_back and int_progress % 2 == 1:
39 | progress = 1 - progress
40 |
41 | reduce_t = progress * self.duration
42 |
43 | has_active_animation = False
44 | for animation in self:
45 | if animation is None:
46 | continue
47 |
48 | if reduce_t < animation.total_duration:
49 | animation._go_to(reduce_t)
50 | has_active_animation = True
51 |
52 | if not has_active_animation:
53 | self._running = False
54 | return
55 |
56 | if self.running_callback is not None:
57 | self.running_callback(t)
58 |
--------------------------------------------------------------------------------
/glass_engine/Animations/SequentialAnimation.py:
--------------------------------------------------------------------------------
1 | from .AnimationGroup import AnimationGroup
2 |
3 |
4 | class SequentialAnimation(AnimationGroup):
5 |
6 | def __init__(self, *animations, **kwargs):
7 | AnimationGroup.__init__(self, *animations, **kwargs)
8 |
9 | def _update_duration(self):
10 | if not self._total_duration_dirty:
11 | return
12 |
13 | self._duration = 0
14 | for animation in self:
15 | self._duration += animation.total_duration
16 |
17 | self._total_duration = self._duration * self.loops
18 | if self._go_back:
19 | self._total_duration *= 2
20 |
21 | self._total_duration_dirty = False
22 |
23 | def _go_to(self, t: float):
24 | if t > self.total_duration:
25 | t = self.total_duration
26 | self._running = False
27 |
28 | progress = t / self.duration
29 | int_progress = int(progress)
30 | if progress != int_progress:
31 | progress -= int_progress
32 | elif progress != 0:
33 | progress = 1
34 | else:
35 | progress = 0
36 |
37 | if self.go_back and int_progress % 2 == 1:
38 | progress = 1 - progress
39 |
40 | reduce_t = progress * self.duration
41 |
42 | accum_time = 0
43 | next_accum_time = 0
44 | active_animation = None
45 | for animation in self:
46 | if animation is None:
47 | continue
48 |
49 | next_accum_time += animation.total_duration
50 | if accum_time <= reduce_t < next_accum_time:
51 | active_animation = animation
52 | break
53 | accum_time = next_accum_time
54 |
55 | if active_animation is None:
56 | self._running = False
57 | return
58 |
59 | active_animation._go_to(reduce_t - accum_time)
60 |
61 | if self.running_callback is not None:
62 | self.running_callback(t)
63 |
--------------------------------------------------------------------------------
/glass_engine/Animations/__init__.py:
--------------------------------------------------------------------------------
1 | from .Animation import Animation
2 | from .EasingCurve import EasingCurve
3 | from .Chronoscope import Chronoscope
4 | from .SequentialAnimation import SequentialAnimation
5 | from .ParallelAnimation import ParallelAnimation
6 |
--------------------------------------------------------------------------------
/glass_engine/Background.py:
--------------------------------------------------------------------------------
1 | from .SkyBox import SkyBox
2 | from .SkyDome import SkyDome
3 |
4 | from glass import samplerCube, sampler2D
5 |
6 | import glm
7 | from typing import Union
8 |
9 |
10 | class Background:
11 | def __init__(self):
12 | self._skybox: SkyBox = SkyBox()
13 | self._skydome: SkyDome = SkyDome()
14 | self._color: glm.vec4 = glm.vec4(0, 0, 0, 1)
15 | self._distance: float = 100.0
16 |
17 | @property
18 | def skybox(self):
19 | return self._skybox
20 |
21 | @skybox.setter
22 | def skybox(self, skybox_map: samplerCube):
23 | self._skybox.skybox_map = skybox_map
24 |
25 | @property
26 | def skydome(self):
27 | return self._skydome
28 |
29 | @skydome.setter
30 | def skydome(self, image: str):
31 | self._skydome.skydome_map = image
32 |
33 | @property
34 | def skybox_map(self) -> samplerCube:
35 | return self._skybox.skybox_map
36 |
37 | @property
38 | def skydome_map(self) -> sampler2D:
39 | return self._skydome.skydome_map
40 |
41 | @property
42 | def distance(self) -> float:
43 | return self._distance
44 |
45 | @distance.setter
46 | def distance(self, distance: float) -> None:
47 | self._distance = distance
48 |
49 | @property
50 | def color(self) -> glm.vec4:
51 | return self._color
52 |
53 | @color.setter
54 | def color(self, color: Union[glm.vec4, glm.vec3]) -> None:
55 | if isinstance(color, glm.vec3):
56 | color = glm.vec4(color, 1)
57 |
58 | self._color = color
59 |
--------------------------------------------------------------------------------
/glass_engine/BasicScene.py:
--------------------------------------------------------------------------------
1 | from .Scene import Scene
2 | from .Camera import Camera
3 | from .Geometries.Floor import Floor
4 | from .Lights.DirLight import DirLight
5 | from .Manipulators import ModelViewManipulator
6 |
7 |
8 | def SceneRoam(add_floor=True):
9 | scene = Scene()
10 |
11 | camera = Camera()
12 | camera.position.y = -5
13 | camera.position.z = 1.7
14 | camera.pitch = -10
15 | scene.add(camera)
16 |
17 | floor = None
18 | if add_floor:
19 | floor = Floor()
20 | scene.add(floor)
21 |
22 | dir_light = DirLight()
23 | dir_light.pitch = -45
24 | dir_light.yaw = 45
25 | scene.add(dir_light)
26 |
27 | return scene, camera, dir_light, floor
28 |
29 |
30 | def ModelView(distance: float = 5, azimuth_deg: float = 0, elevation_deg: float = 0):
31 | scene = Scene()
32 |
33 | camera = Camera()
34 | camera.screen.manipulator = ModelViewManipulator(
35 | distance, azimuth_deg, elevation_deg
36 | )
37 | scene.add(camera)
38 |
39 | dir_light = DirLight()
40 | dir_light.pitch = -45
41 | dir_light.yaw = 45
42 | scene.add(dir_light)
43 |
44 | return scene, camera, dir_light
45 |
--------------------------------------------------------------------------------
/glass_engine/Frame.py:
--------------------------------------------------------------------------------
1 | from glass import ShaderProgram, sampler2D, GLConfig, sampler2DArray
2 |
3 | import os
4 | from OpenGL import GL
5 | from typing import Union
6 |
7 |
8 | class Frame:
9 |
10 | def __init__(self):
11 | self._program = None
12 |
13 | @property
14 | def program(self):
15 | if self._program is None:
16 | self._program = ShaderProgram()
17 | self._program.compile(self.draw_frame_vs)
18 | self._program.compile(self.draw_frame_fs)
19 | self._program.uniform_not_set_warning = False
20 |
21 | return self._program
22 |
23 | @property
24 | def draw_frame_vs(self) -> str:
25 | self_folder = os.path.dirname(os.path.abspath(__file__))
26 | return os.path.abspath(self_folder + "/../glass/glsl/draw_frame.vert").replace(
27 | "\\", "/"
28 | )
29 |
30 | @property
31 | def draw_frame_fs(self) -> str:
32 | self_folder = os.path.dirname(os.path.abspath(__file__))
33 | return os.path.abspath(self_folder + "/glsl/Pipelines/draw_frame.frag").replace(
34 | "\\", "/"
35 | )
36 |
37 | def draw(
38 | self,
39 | screen_image: Union[sampler2D, sampler2DArray],
40 | gray: bool = False,
41 | invert: bool = False,
42 | layer: int = -1,
43 | index: int = 0,
44 | ):
45 | with GLConfig.LocalEnv():
46 | GLConfig.cull_face = None
47 | GLConfig.polygon_mode = GL.GL_FILL
48 |
49 | if isinstance(screen_image, sampler2D):
50 | self.program["screen_image"] = screen_image
51 | self.program["layer"] = -1
52 | else:
53 | self.program["screen_image_array"] = screen_image
54 | self.program["layer"] = layer
55 |
56 | self.program["gray"] = gray
57 | self.program["invert"] = invert
58 | self.program["index"] = index
59 | self.program.draw_triangles(vertices=self._vertices, indices=self._indices)
60 |
61 |
62 | Frame = Frame()
63 |
--------------------------------------------------------------------------------
/glass_engine/Geometries/CoordSys.py:
--------------------------------------------------------------------------------
1 | from .Cylinder import Cylinder
2 | from .Cone import Cone
3 | from ..SceneNode import SceneNode
4 |
5 | from typing import Union
6 |
7 | import glm
8 |
9 |
10 | class CoordSys(SceneNode):
11 |
12 | def __init__(
13 | self,
14 | x_length: float = 1,
15 | y_length: Union[float, None] = None,
16 | z_length: Union[float, None] = None,
17 | alpha: float = 1,
18 | name: str = "",
19 | ):
20 | SceneNode.__init__(self, name=name)
21 |
22 | if y_length is None:
23 | y_length = x_length
24 |
25 | if z_length is None:
26 | z_length = x_length
27 |
28 | x_axis = CoordSys.create_axis(x_length, glm.vec4(1, 0, 0, alpha))
29 | x_axis.roll = 90
30 | self.add_child(x_axis)
31 |
32 | y_axis = CoordSys.create_axis(y_length, glm.vec4(0, 1, 0, alpha))
33 | y_axis.pitch = -90
34 | self.add_child(y_axis)
35 |
36 | z_axis = CoordSys.create_axis(z_length, glm.vec4(0, 0, 1, alpha))
37 | self.add_child(z_axis)
38 |
39 | @staticmethod
40 | def create_axis(length: float, color: glm.vec4):
41 | axis = Cylinder(0.015, length, color=color)
42 | arrow = Cone(0.04, 0.15, color=color)
43 | arrow.position.z = length
44 | axis.add_child(arrow)
45 |
46 | return axis
47 |
--------------------------------------------------------------------------------
/glass_engine/Geometries/Point.py:
--------------------------------------------------------------------------------
1 | from ..Mesh import Mesh
2 |
3 | from glass import Vertex
4 | from glass.utils import checktype
5 |
6 | import glm
7 | from OpenGL import GL
8 | from typing import Union
9 |
10 |
11 | class Point(Mesh):
12 |
13 | def __init__(
14 | self,
15 | position: glm.vec3 = glm.vec3(0),
16 | color: Union[glm.vec3, glm.vec4] = glm.vec4(0.396, 0.74151, 0.69102, 1),
17 | point_size: int = 5,
18 | name: str = "",
19 | ):
20 | Mesh.__init__(self, primitive_type=GL.GL_POINTS, color=color, name=name)
21 | self.render_hints.point_size = point_size
22 | self.__position = position
23 |
24 | def build(self):
25 | position = self.__position
26 | vertices = self._vertices
27 |
28 | vertices[0] = Vertex(position=position, tex_coord=glm.vec3(0.5, 0.5, 0))
29 | del vertices[1:]
30 |
31 | @property
32 | def position(self):
33 | return self.__position
34 |
35 | @position.setter
36 | @Mesh.param_setter
37 | def position(self, position: glm.vec3):
38 | self.__position = position
39 |
40 | @property
41 | def point_size(self):
42 | return self.render_hints.point_size
43 |
44 | @point_size.setter
45 | @checktype
46 | def point_size(self, point_size: int):
47 | self.render_hints.point_size = point_size
48 |
--------------------------------------------------------------------------------
/glass_engine/Geometries/Points.py:
--------------------------------------------------------------------------------
1 | from ..Mesh import Mesh
2 |
3 | from glass import Vertex
4 | from glass.utils import checktype
5 |
6 | import glm
7 | from OpenGL import GL
8 | from typing import Union
9 |
10 |
11 | class Points(Mesh):
12 |
13 | def __init__(
14 | self,
15 | points: list = [],
16 | color: Union[glm.vec3, glm.vec4] = glm.vec4(0.396, 0.74151, 0.69102, 1),
17 | point_size: int = 5,
18 | name: str = "",
19 | block: bool = True,
20 | ):
21 | Mesh.__init__(
22 | self,
23 | primitive_type=GL.GL_POINTS,
24 | color=color,
25 | name=name,
26 | block=block
27 | )
28 | self.render_hints.point_size = point_size
29 | self.__points = points
30 |
31 | def build(self):
32 | points = self.__points
33 | vertices = self._vertices
34 |
35 | length = 0
36 | len_points = len(points)
37 | for i in range(len_points):
38 | if i > 0:
39 | length += glm.length(points[i] - points[i - 1])
40 | vertices[i] = Vertex(position=points[i], tex_coord=glm.vec3(length, 0, 0))
41 |
42 | del vertices[len_points:]
43 |
44 | @property
45 | def points(self):
46 | return self.__points
47 |
48 | @points.setter
49 | def points(self, points):
50 | self.__points = points
51 | self._build_state = Mesh.BuildState.NotBuilt
52 |
53 | @property
54 | def point_size(self):
55 | return self.render_hints.point_size
56 |
57 | @point_size.setter
58 | @checktype
59 | def point_size(self, point_size: int):
60 | self.render_hints.point_size = point_size
61 |
--------------------------------------------------------------------------------
/glass_engine/Geometries/Polyline.py:
--------------------------------------------------------------------------------
1 | from ..Mesh import Mesh
2 |
3 | from glass import Vertex
4 | from glass.utils import checktype
5 |
6 | import glm
7 | from OpenGL import GL
8 | from typing import Union
9 |
10 |
11 | class Polyline(Mesh):
12 |
13 | def __init__(
14 | self,
15 | points: list = [],
16 | color: Union[glm.vec3, glm.vec4] = glm.vec4(0.396, 0.74151, 0.69102, 1),
17 | line_width: int = 2,
18 | loop: bool = False,
19 | name: str = "",
20 | block: bool = True,
21 | ):
22 | primitive_type = GL.GL_LINE_STRIP if not loop else GL.GL_LINE_LOOP
23 | Mesh.__init__(
24 | self,
25 | primitive_type=primitive_type,
26 | color=color,
27 | name=name,
28 | block=block
29 | )
30 | self.render_hints.line_width = line_width
31 | self.__points = points
32 |
33 | def build(self):
34 | points = self.__points
35 | vertices = self._vertices
36 |
37 | length = 0
38 | len_points = len(points)
39 | for i in range(len_points):
40 | if i > 0:
41 | length += glm.length(points[i] - points[i - 1])
42 | bitangent = None
43 | if i < len_points - 1:
44 | bitangent = glm.normalize(points[i + 1] - points[i])
45 | else:
46 | bitangent = glm.normalize(points[i] - points[i - 1])
47 | vertices[i] = Vertex(
48 | position=points[i],
49 | bitangent=bitangent,
50 | tex_coord=glm.vec3(length, 0, 0),
51 | )
52 |
53 | del vertices[len_points:]
54 |
55 | @property
56 | def points(self):
57 | return self.__points
58 |
59 | @points.setter
60 | def points(self, points):
61 | self.__points = points
62 | self._build_state = Mesh.BuildState.NotBuilt
63 |
64 | @property
65 | def line_width(self):
66 | return self.render_hints.line_width
67 |
68 | @line_width.setter
69 | @checktype
70 | def line_width(self, line_width: int):
71 | self.render_hints.line_width = line_width
72 |
73 | @property
74 | def loop(self):
75 | return self.primitive_type == GL.GL_LINE_LOOP
76 |
77 | @loop.setter
78 | @Mesh.param_setter
79 | def loop(self, flag: bool):
80 | self.primitive_type = GL.GL_LINE_STRIP if not flag else GL.GL_LINE_LOOP
81 |
--------------------------------------------------------------------------------
/glass_engine/Geometries/__init__.py:
--------------------------------------------------------------------------------
1 | # 点
2 | from .Point import Point
3 | from .Points import Points
4 |
5 | # 线
6 | from .Polyline import Polyline
7 | from .Circle import Circle
8 |
9 | # 面
10 | from .RectFace import RectFace
11 |
12 | from .RPolygonFace import RPolygonFace
13 | from .HollowRPolygonFace import HollowRPolygonFace
14 |
15 | from .CircleFace import CircleFace
16 | from .TorusFace import TorusFace
17 | from .EllipseFace import EllipseFace
18 |
19 | # 体
20 |
21 | # 多面体
22 | from .Box import Box
23 |
24 | from .Prism import Prism
25 | from .PrismSide import PrismSide
26 |
27 | from .Pyramid import Pyramid
28 | from .PyramidSide import PyramidSide
29 |
30 | from .PyramidTrustum import PyramidTrustum
31 | from .PyramidTrustumSide import PyramidTrustumSide
32 |
33 | # 曲面体
34 | from .Cylinder import Cylinder
35 | from .CylinderSide import CylinderSide
36 |
37 | from .Cone import Cone
38 | from .ConeSide import ConeSide
39 | from .ConeTrustum import ConeTrustum
40 | from .ConeTrustumSide import ConeTrustumSide
41 |
42 | from .Sphere import Sphere
43 | from .Icosphere import Icosphere
44 | from .SphericalCap import SphericalCap
45 | from .SphericalCapTop import SphericalCapTop
46 |
47 | # 正多面体
48 | from .Tetrahedron import Tetrahedron # 正四面体
49 | from .Hexahedron import Hexahedron # 正六面体
50 | from .Octahedron import Octahedron # 正八面体
51 | from .Dodecahedron import Dodecahedron # 正十二面体
52 | from .Icosahedron import Icosahedron # 正二十面体
53 |
54 | # 通用函数曲面
55 | from .Surf import Surf
56 | from .FSurf import FSurf
57 | from .CylindricalFSurf import CylindricalFSurf
58 | from .SphericalFSurf import SphericalFSurf
59 |
60 | # 变形体
61 | from .Rotator import Rotator
62 | from .Extruder import Extruder
63 |
64 | # 特殊几何体
65 | from .Floor import Floor
66 | from .Torus import Torus
67 | from .TrefoilKnot import TrefoilKnot
68 | from .CoordSys import CoordSys
69 | from .ImageQuad import ImageQuad
70 |
--------------------------------------------------------------------------------
/glass_engine/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023-2024 王炳辉 (binghui.wang@foxmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/glass_engine/Lights/DirLight.py:
--------------------------------------------------------------------------------
1 | from .Light import Light, FlatLight
2 | from glass.DictList import DictList
3 | from glass import Block
4 |
5 | import glm
6 | from typing import Union
7 |
8 |
9 | class DirLight(Light):
10 | pass
11 |
12 |
13 | class FlatDirLight(FlatLight):
14 |
15 | def __init__(self, dir_light: DirLight):
16 | self.direction = glm.vec3(0, 1, 0)
17 | self.abs_orientation = glm.quat(1, 0, 0, 0)
18 | self.max_back_offset = 0
19 | FlatLight.__init__(self, dir_light)
20 |
21 |
22 | class DirLights(Block.HostClass):
23 |
24 | def __init__(self):
25 | Block.HostClass.__init__(self)
26 | self.dir_lights = DictList()
27 |
28 | def __getitem__(self, key: Union[str, int]):
29 | return self.dir_lights[key]
30 |
31 | @Block.HostClass.not_const
32 | def __setitem__(self, key: Union[str, int], dir_light: FlatDirLight):
33 | self.dir_lights[key] = dir_light
34 |
35 | @Block.HostClass.not_const
36 | def __delitem__(self, key: Union[str, int]):
37 | del self.dir_lights[key]
38 |
39 | def __contains__(self, path_str: str):
40 | return path_str in self.dir_lights
41 |
42 | def __len__(self):
43 | return len(self.dir_lights)
44 |
45 | def __iter__(self):
46 | return iter(self.dir_lights)
47 |
48 | def keys(self):
49 | return self.dir_lights.keys()
50 |
51 | @property
52 | def n_dir_lights(self):
53 | return len(self.dir_lights)
54 |
--------------------------------------------------------------------------------
/glass_engine/Lights/__init__.py:
--------------------------------------------------------------------------------
1 | from .DirLight import DirLight
2 | from .PointLight import PointLight
3 | from .SpotLight import SpotLight
4 |
--------------------------------------------------------------------------------
/glass_engine/Manipulators/__init__.py:
--------------------------------------------------------------------------------
1 | from .Manipulator import Manipulator
2 | from .ModelViewManipulator import ModelViewManipulator
3 | from .SceneRoamManipulator import SceneRoamManipulator
4 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/ACESToneMapper.py:
--------------------------------------------------------------------------------
1 | from .ShaderEffect import ShaderEffect
2 | import os
3 |
4 |
5 | class ACESToneMapper(ShaderEffect):
6 |
7 | def __init__(self):
8 | self_folder = os.path.dirname(os.path.abspath(__file__))
9 | ShaderEffect.__init__(
10 | self, self_folder + "/../glsl/PostProcessEffects/ACES_tone_mapper.glsl"
11 | )
12 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/ExposureAdaptor.py:
--------------------------------------------------------------------------------
1 | from .ShaderEffect import ShaderEffect
2 | from glass import sampler2D, Block
3 |
4 | import time
5 | import os
6 |
7 |
8 | class ExposureAdaptor(ShaderEffect):
9 |
10 | class CurrentLuma(Block.HostClass):
11 | def __init__(self):
12 | Block.HostClass.__init__(self)
13 | self._current_luma = 0
14 |
15 | @property
16 | def current_luma(self):
17 | return self._current_luma
18 |
19 | @current_luma.setter
20 | @Block.HostClass.not_const
21 | def current_luma(self, luma: float):
22 | self._current_luma = luma
23 |
24 | def __init__(self):
25 | self_folder = os.path.dirname(os.path.abspath(__file__))
26 | ShaderEffect.__init__(
27 | self,
28 | self_folder + "/../glsl/PostProcessEffects/exposure_adaptor.glsl",
29 | generate_mipmap=True,
30 | )
31 |
32 | self.current_luma = ExposureAdaptor.CurrentLuma()
33 | self["CurrentLuma"] = self.current_luma
34 |
35 | def apply(self, screen_image: sampler2D) -> sampler2D:
36 | self.program["fps"] = self.camera.screen.smooth_fps
37 | return ShaderEffect.apply(self, screen_image)
38 |
39 | def draw_to_active(self, screen_image: sampler2D) -> None:
40 | self.program["fps"] = self.camera.screen.smooth_fps
41 | ShaderEffect.draw_to_active(self, screen_image)
42 |
43 | @property
44 | def should_update_until(self)->float:
45 | if not self._enabled:
46 | return 0
47 |
48 | if self.camera is None:
49 | return 0
50 |
51 | if (not self.camera.lens.auto_explosure) or self.camera.lens.local_explosure:
52 | return 0
53 |
54 | return self.camera.screen.scene_update_time + self.camera.lens.explosure_adapt_time
55 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/LUTEffect.py:
--------------------------------------------------------------------------------
1 | from .ShaderEffect import ShaderEffect
2 | from .PostProcessEffect import PostProcessEffect
3 | from .. import lut
4 | from glass import sampler2D
5 | from glass.utils import extname
6 |
7 | import numpy as np
8 | import os
9 | from OpenGL import GL
10 | from typing import Union
11 |
12 |
13 | class LUTEffect(ShaderEffect):
14 |
15 | def __init__(self, LUT: Union[str, np.ndarray, sampler2D], contribute: float = 1.0):
16 | self_folder = os.path.dirname(os.path.abspath(__file__))
17 | ShaderEffect.__init__(
18 | self, self_folder + "/../glsl/PostProcessEffects/lut.glsl"
19 | )
20 |
21 | if isinstance(LUT, str) and extname(LUT) == "cube":
22 | LUT = lut.cube_to_LUT(LUT)
23 |
24 | if not isinstance(LUT, sampler2D):
25 | LUT = sampler2D(LUT)
26 |
27 | LUT.wrap = GL.GL_CLAMP_TO_EDGE
28 | self["LUT"] = LUT
29 | self["contribute"] = contribute
30 | self.__LUT = LUT
31 | self.__contribute = contribute
32 |
33 | @property
34 | def LUT(self):
35 | return self.__LUT
36 |
37 | @LUT.setter
38 | @PostProcessEffect.param_setter
39 | def LUT(self, LUT: Union[str, np.ndarray, sampler2D]):
40 | if isinstance(LUT, str) and extname(LUT) == "cube":
41 | LUT = lut.cube_to_LUT(LUT)
42 |
43 | if not isinstance(LUT, sampler2D):
44 | LUT = sampler2D(LUT)
45 |
46 | LUT.wrap = GL.GL_CLAMP_TO_EDGE
47 | self.__LUT = LUT
48 | self["LUT"] = LUT
49 |
50 | @property
51 | def contribute(self):
52 | return self.__contribute
53 |
54 | @contribute.setter
55 | @PostProcessEffect.param_setter
56 | def contribute(self, contribute: float):
57 | self.__contribute = contribute
58 | self["contribute"] = contribute
59 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/MedianBlur.py:
--------------------------------------------------------------------------------
1 | from .ShaderEffect import ShaderEffect
2 | import os
3 |
4 |
5 | class MedianBlur(ShaderEffect):
6 |
7 | def __init__(self):
8 | self_folder = os.path.dirname(os.path.abspath(__file__))
9 | ShaderEffect.__init__(
10 | self, self_folder + "/../glsl/PostProcessEffects/median_gray_blur5.glsl"
11 | )
12 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/MulFilter.py:
--------------------------------------------------------------------------------
1 | from .ShaderEffect import ShaderEffect
2 | import os
3 |
4 |
5 | class MulFilter(ShaderEffect):
6 |
7 | def __init__(self):
8 | self_folder = os.path.dirname(os.path.abspath(__file__))
9 | ShaderEffect.__init__(
10 | self, self_folder + "/../glsl/PostProcessEffects/mul_filter.glsl"
11 | )
12 |
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/PostProcessEffect.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from glass import sampler2D
3 | from glass.utils import checktype
4 |
5 | from functools import wraps
6 |
7 |
8 | class PostProcessEffect(ABC):
9 |
10 | def __init__(self):
11 | self._enabled = True
12 |
13 | self.depth_map = None
14 | self.world_pos_map = None
15 | self.world_normal_map = None
16 | self.camera = None
17 |
18 | def __bool__(self) -> bool:
19 | return self._enabled
20 |
21 | def param_setter(func):
22 | @wraps(func)
23 | def wrapper(*args, **kwargs):
24 | self = args[0]
25 | value = args[1]
26 |
27 | equal = False
28 | try:
29 | lvalue = getattr(self, func.__name__)
30 | if type(lvalue) != type(value):
31 | equal = False
32 | else:
33 | equal = bool(getattr(self, func.__name__) == value)
34 | except:
35 | equal = False
36 |
37 | if equal:
38 | return
39 |
40 | safe_func = checktype(func)
41 | return_value = safe_func(*args, **kwargs)
42 | if self.camera is not None:
43 | self.camera.screen.update_PPEs()
44 |
45 | return return_value
46 |
47 | return wrapper
48 |
49 | @abstractmethod
50 | def apply(self, screen_image: sampler2D) -> sampler2D:
51 | pass
52 |
53 | @abstractmethod
54 | def draw_to_active(self, screen_image: sampler2D) -> None:
55 | pass
56 |
57 | @abstractmethod
58 | def need_pos_info(self) -> bool:
59 | return False
60 |
61 | @property
62 | def enabled(self) -> bool:
63 | return self._enabled
64 |
65 | @enabled.setter
66 | @param_setter
67 | def enabled(self, flag: bool):
68 | self._enabled = flag
69 |
70 | @property
71 | def should_update_until(self)->float:
72 | return 0.0
--------------------------------------------------------------------------------
/glass_engine/PostProcessEffects/__init__.py:
--------------------------------------------------------------------------------
1 | from .PostProcessEffects import PostProcessEffects
2 | from .PostProcessEffect import PostProcessEffect
3 | from .ShaderEffect import ShaderEffect
4 |
5 | from .GaussBlur import GaussBlur
6 | from .KernelFilter import KernelFilter
7 | from .BloomEffect import BloomEffect
8 | from .ACESToneMapper import ACESToneMapper
9 | from .DOFEffect import DOFEffect
10 | from .FXAAEffect import FXAAEffect
11 | from .LUTEffect import LUTEffect
12 | from .SSAOEffect import SSAOEffect
13 | from .MulFilter import MulFilter
14 | from .ExposureAdaptor import ExposureAdaptor
15 |
--------------------------------------------------------------------------------
/glass_engine/Renderers/Renderer.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class Renderer(ABC):
5 |
6 | def __init__(self):
7 | self._camera = None
8 |
9 | @property
10 | def camera(self):
11 | return self._camera
12 |
13 | @property
14 | def scene(self):
15 | return self.camera.scene
16 |
17 | @property
18 | def screen(self):
19 | return self.camera.screen
20 |
21 | def startup(self):
22 | pass
23 |
24 | @abstractmethod
25 | def render(self) -> bool:
26 | pass
27 |
--------------------------------------------------------------------------------
/glass_engine/Renderers/__init__.py:
--------------------------------------------------------------------------------
1 | from .Renderer import Renderer
2 | from .ForwardRenderer import ForwardRenderer
3 | from .DeferredRenderer import DeferredRenderer
4 |
--------------------------------------------------------------------------------
/glass_engine/Screens/PyQt5Screen.py:
--------------------------------------------------------------------------------
1 | from glass.download import pip_install
2 | from .QtScreen import init_QtScreen
3 | from ..Manipulators.Manipulator import Manipulator
4 |
5 | try:
6 | import PyQt5
7 | except ModuleNotFoundError:
8 | pip_install("PyQt5")
9 | import PyQt5
10 |
11 | from PyQt5.QtWidgets import QOpenGLWidget
12 |
13 | import glm
14 |
15 |
16 | @init_QtScreen
17 | class PyQt5Screen(QOpenGLWidget):
18 | mouse_pressed = PyQt5.QtCore.pyqtSignal(Manipulator.MouseButton, glm.vec2, glm.vec2)
19 | mouse_released = PyQt5.QtCore.pyqtSignal(
20 | Manipulator.MouseButton, glm.vec2, glm.vec2
21 | )
22 | mouse_double_clicked = PyQt5.QtCore.pyqtSignal(
23 | Manipulator.MouseButton, glm.vec2, glm.vec2
24 | )
25 | mouse_moved = PyQt5.QtCore.pyqtSignal(glm.vec2, glm.vec2)
26 | wheel_scrolled = PyQt5.QtCore.pyqtSignal(glm.vec2, glm.vec2, glm.vec2)
27 | key_pressed = PyQt5.QtCore.pyqtSignal(Manipulator.Key)
28 | key_released = PyQt5.QtCore.pyqtSignal(Manipulator.Key)
29 | key_repeated = PyQt5.QtCore.pyqtSignal(set)
30 | frame_started = PyQt5.QtCore.pyqtSignal()
31 | frame_ended = PyQt5.QtCore.pyqtSignal()
32 |
--------------------------------------------------------------------------------
/glass_engine/Screens/PyQt6Screen.py:
--------------------------------------------------------------------------------
1 | from glass.download import pip_install
2 | from .QtScreen import init_QtScreen
3 | from ..Manipulators.Manipulator import Manipulator
4 |
5 | try:
6 | import PyQt6
7 | except ModuleNotFoundError:
8 | pip_install("PyQt6")
9 | import PyQt6
10 |
11 | from PyQt6.QtOpenGLWidgets import QOpenGLWidget
12 |
13 | import glm
14 |
15 |
16 | @init_QtScreen
17 | class PyQt6Screen(QOpenGLWidget):
18 | mouse_pressed = PyQt6.QtCore.pyqtSignal(Manipulator.MouseButton, glm.vec2, glm.vec2)
19 | mouse_released = PyQt6.QtCore.pyqtSignal(
20 | Manipulator.MouseButton, glm.vec2, glm.vec2
21 | )
22 | mouse_double_clicked = PyQt6.QtCore.pyqtSignal(
23 | Manipulator.MouseButton, glm.vec2, glm.vec2
24 | )
25 | mouse_moved = PyQt6.QtCore.pyqtSignal(glm.vec2, glm.vec2)
26 | wheel_scrolled = PyQt6.QtCore.pyqtSignal(glm.vec2, glm.vec2, glm.vec2)
27 | key_pressed = PyQt6.QtCore.pyqtSignal(Manipulator.Key)
28 | key_released = PyQt6.QtCore.pyqtSignal(Manipulator.Key)
29 | key_repeated = PyQt6.QtCore.pyqtSignal(set)
30 | frame_started = PyQt6.QtCore.pyqtSignal()
31 | frame_ended = PyQt6.QtCore.pyqtSignal()
32 |
--------------------------------------------------------------------------------
/glass_engine/Screens/PySide2Screen.py:
--------------------------------------------------------------------------------
1 | from glass.download import pip_install
2 | from .QtScreen import init_QtScreen
3 | from ..Manipulators.Manipulator import Manipulator
4 |
5 | try:
6 | import PySide2
7 | except ModuleNotFoundError:
8 | pip_install("PySide2")
9 | import PySide2
10 |
11 | from PySide2.QtOpenGLWidgets import QOpenGLWidget
12 |
13 | import glm
14 |
15 |
16 | @init_QtScreen
17 | class PySide2Screen(QOpenGLWidget):
18 | mouse_pressed = PySide2.QtCore.Signal(Manipulator.MouseButton, glm.vec2, glm.vec2)
19 | mouse_released = PySide2.QtCore.Signal(Manipulator.MouseButton, glm.vec2, glm.vec2)
20 | mouse_double_clicked = PySide2.QtCore.Signal(
21 | Manipulator.MouseButton, glm.vec2, glm.vec2
22 | )
23 | mouse_moved = PySide2.QtCore.Signal(glm.vec2, glm.vec2)
24 | wheel_scrolled = PySide2.QtCore.Signal(glm.vec2, glm.vec2, glm.vec2)
25 | key_pressed = PySide2.QtCore.Signal(Manipulator.Key)
26 | key_released = PySide2.QtCore.Signal(Manipulator.Key)
27 | key_repeated = PySide2.QtCore.Signal(set)
28 | frame_started = PySide2.QtCore.Signal()
29 | frame_ended = PySide2.QtCore.Signal()
30 |
--------------------------------------------------------------------------------
/glass_engine/Screens/PySide6Screen.py:
--------------------------------------------------------------------------------
1 | from glass.download import pip_install
2 | from .QtScreen import init_QtScreen
3 | from ..Manipulators.Manipulator import Manipulator
4 |
5 | try:
6 | import PySide6
7 | except ModuleNotFoundError:
8 | pip_install("PySide6")
9 | import PySide6
10 |
11 | from PySide6.QtOpenGLWidgets import QOpenGLWidget
12 |
13 | import glm
14 |
15 |
16 | @init_QtScreen
17 | class PySide6Screen(QOpenGLWidget):
18 | mouse_pressed = PySide6.QtCore.Signal(Manipulator.MouseButton, glm.vec2, glm.vec2)
19 | mouse_released = PySide6.QtCore.Signal(Manipulator.MouseButton, glm.vec2, glm.vec2)
20 | mouse_double_clicked = PySide6.QtCore.Signal(
21 | Manipulator.MouseButton, glm.vec2, glm.vec2
22 | )
23 | mouse_moved = PySide6.QtCore.Signal(glm.vec2, glm.vec2)
24 | wheel_scrolled = PySide6.QtCore.Signal(glm.vec2, glm.vec2, glm.vec2)
25 | key_pressed = PySide6.QtCore.Signal(Manipulator.Key)
26 | key_released = PySide6.QtCore.Signal(Manipulator.Key)
27 | key_repeated = PySide6.QtCore.Signal(set)
28 | frame_started = PySide6.QtCore.Signal()
29 | frame_ended = PySide6.QtCore.Signal()
30 |
--------------------------------------------------------------------------------
/glass_engine/Screens/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/glass_engine/Screens/__init__.py
--------------------------------------------------------------------------------
/glass_engine/SlideAverageFilter.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 |
4 | class SlideAverageFilter:
5 |
6 | def __init__(self, window_width: int = 10) -> None:
7 | self._current_sum = 0
8 | self._window_width = window_width
9 | self._data_list = []
10 |
11 | def __call__(self, new_value: Union[float, int]) -> float:
12 | if len(self._data_list) >= self._window_width:
13 | old_value = self._data_list.pop(0)
14 | self._current_sum -= old_value
15 |
16 | self._data_list.append(new_value)
17 | self._current_sum += new_value
18 |
19 | return self._current_sum / len(self._data_list)
20 |
21 | @property
22 | def window_width(self) -> int:
23 | return self._window_width
24 |
25 | @window_width.setter
26 | def window_width(self, window_width: int) -> None:
27 | self._window_width = window_width
28 |
--------------------------------------------------------------------------------
/glass_engine/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = "0.1.64"
2 |
3 | from .Scene import Scene
4 | from .SceneNode import SceneNode
5 | from .BasicScene import SceneRoam, ModelView
6 |
7 | from .Camera import Camera
8 | from .Material import Material
9 | from .Mesh import Mesh
10 | from .Model import Model
11 |
12 | from .ColorMap import ColorMap
13 | from .Frame import Frame
14 | from .Fog import Fog
15 |
16 | import glm
17 |
18 | from OpenGL import GL
19 | from glass import GlassConfig
20 |
--------------------------------------------------------------------------------
/glass_engine/__pyinstaller/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | def get_hook_dirs():
5 | return [os.path.dirname(os.path.abspath(__file__)).replace("\\", "/")]
6 |
--------------------------------------------------------------------------------
/glass_engine/__pyinstaller/hook-glass_engine.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | def find_files(directory):
5 | file_list = []
6 | abs_directory = (
7 | os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/..").replace(
8 | "\\", "/"
9 | )
10 | + "/"
11 | + directory
12 | )
13 | for root, _, files in os.walk(abs_directory):
14 | for file in files:
15 | file_path = os.path.abspath(os.path.join(root, file)).replace("\\", "/")
16 | if not os.path.isfile(file_path):
17 | continue
18 |
19 | target_path = (
20 | "glass_engine/"
21 | + directory
22 | + file_path[
23 | len(abs_directory) : (-len(os.path.basename(file_path)) - 1)
24 | ]
25 | )
26 | if "__glcache__" not in file_path and "__pycache__" not in file_path:
27 | file_list.append((file_path.replace("\\", "/"), target_path))
28 | return file_list
29 |
30 | self_folder = os.path.dirname(os.path.abspath(__file__))
31 | datas = find_files("glsl")
32 | datas.extend(
33 | [
34 | (
35 | os.path.abspath(self_folder + "/../images/glass_engine_logo64.png").replace("\\", "/"),
36 | "glass_engine/images",
37 | ),
38 | (
39 | os.path.abspath(self_folder + "/../LICENSE").replace("\\", "/"),
40 | "glass_engine",
41 | )
42 | ]
43 | )
44 |
45 | hiddenimports = [
46 | "glass_engine.Screens.PyQt5Screen",
47 | "glass_engine.Screens.PyQt6Screen",
48 | "glass_engine.Screens.PySide2Screen",
49 | "glass_engine.Screens.PySide6Screen",
50 | "glass_engine.Screens.QtScreen",
51 | ]
52 |
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/DirLight.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _DIRLIGHT_GLSL_
2 | #define _DIRLIGHT_GLSL_
3 |
4 | #include "../include/quat.glsl"
5 |
6 | struct DirLight
7 | {
8 | vec3 color;
9 | bool generate_shadows;
10 | uvec2 depth_map_handle;
11 | float max_back_offset;
12 | float rim_power;
13 | vec3 direction;
14 | quat abs_orientation;
15 | };
16 |
17 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/Lights.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _LIGHTS_GLSL_
2 | #define _LIGHTS_GLSL_
3 |
4 | #include "DirLight.glsl"
5 | #include "PointLight.glsl"
6 | #include "SpotLight.glsl"
7 |
8 | #if USE_SHADER_STORAGE_BLOCK
9 |
10 | buffer DirLights
11 | {
12 | int n_dir_lights;
13 | DirLight dir_lights[];
14 | };
15 |
16 | buffer PointLights
17 | {
18 | int n_point_lights;
19 | PointLight point_lights[];
20 | };
21 |
22 | buffer SpotLights
23 | {
24 | int n_spot_lights;
25 | SpotLight spot_lights[];
26 | };
27 |
28 | #else
29 |
30 | uniform DirLights
31 | {
32 | int n_dir_lights;
33 | DirLight dir_lights[32];
34 | };
35 |
36 | uniform PointLights
37 | {
38 | int n_point_lights;
39 | PointLight point_lights[32];
40 | };
41 |
42 | uniform SpotLights
43 | {
44 | int n_spot_lights;
45 | SpotLight spot_lights[32];
46 | };
47 |
48 | #endif
49 |
50 |
51 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/PointLight.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _POINTLIGHT_GLSL_
2 | #define _POINTLIGHT_GLSL_
3 |
4 | struct PointLight
5 | {
6 | vec3 color;
7 | float rim_power;
8 | float K1;
9 | float K2;
10 | float coverage;
11 | bool generate_shadows;
12 | uvec2 depth_map_handle;
13 | vec3 abs_position;
14 | };
15 |
16 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/PointLight_shadow_mapping.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _POINTLIGHT_SHADOW_MAPPING_GLSL_
2 | #define _POINTLIGHT_SHADOW_MAPPING_GLSL_
3 |
4 | #include "PointLight.glsl"
5 |
6 | float PCF(PointLight light, vec3 frag_pos, vec3 frag_normal)
7 | {
8 | vec3 depth_map_tex_coord = frag_pos - light.abs_position;
9 | float self_depth = length(depth_map_tex_coord);
10 | if (self_depth < 0.1)
11 | {
12 | return 1.0;
13 | }
14 |
15 | depth_map_tex_coord /= self_depth;
16 |
17 | float max_angle_shift = atan(0.05/self_depth);
18 | float beta = acos(max(0, dot(frag_normal, -depth_map_tex_coord)));
19 | float bias = 0.05 * clamp(tan(beta), 0.2, 10.0);
20 | self_depth -= bias;
21 |
22 | int n_samples = 10;
23 | int rand_seed = 0;
24 | int not_occ_count = 0;
25 | int total_count = 0;
26 | quat correction_quat = quat(cos45, sin45, 0, 0);
27 | for (int i = 0; i < n_samples; i++)
28 | {
29 | vec3 sample_dir = rand3_near(depth_map_tex_coord, max_angle_shift, rand_seed);
30 | sample_dir = quat_apply(correction_quat, sample_dir);
31 | float sample_depth = max(texture(samplerCube(light.depth_map_handle), sample_dir).r, 0.0);
32 | sample_depth *= light.coverage;
33 | not_occ_count += (sample_depth > self_depth ? 1 : 0);
34 | total_count += 1;
35 | }
36 |
37 | return 1.0*not_occ_count/total_count;
38 | }
39 |
40 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/SpotLight.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _SPOTLIGHT_GLSL_
2 | #define _SPOTLIGHT_GLSL_
3 |
4 | struct SpotLight
5 | {
6 | vec3 color;
7 | float rim_power;
8 | float half_span_angle_rad;
9 | float half_softness_rad;
10 | float aggregate_coeff;
11 | float K1;
12 | float K2;
13 | float coverage;
14 | bool generate_shadows;
15 | uvec2 depth_map_handle;
16 | vec3 abs_position;
17 | vec3 direction;
18 | };
19 |
20 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Lights/SpotLight_shadow_mapping.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _SPOTLIGHT_SHADOW_MAPPING_GLSL_
2 | #define _SPOTLIGHT_SHADOW_MAPPING_GLSL_
3 |
4 | #include "SpotLight.glsl"
5 |
6 | float PCF(SpotLight light, vec3 frag_pos, vec3 frag_normal)
7 | {
8 | vec3 depth_map_tex_coord = frag_pos - light.abs_position;
9 | float self_depth = length(depth_map_tex_coord);
10 | if (self_depth < 0.1)
11 | return 1;
12 | depth_map_tex_coord /= self_depth;
13 | float theta = acos(dot(normalize(light.direction), depth_map_tex_coord));
14 | float cutoff = soft_step(light.half_span_angle_rad+light.half_softness_rad-theta, light.half_softness_rad);
15 | if (cutoff < 1E-6)
16 | return 1;
17 | float max_angle_shift = atan(0.05/self_depth);
18 | float beta = acos(max(0, dot(frag_normal, -depth_map_tex_coord)));
19 | float bias = 0.05 * clamp(tan(beta), 0.2, 10.0);
20 | self_depth -= bias;
21 |
22 | int n_samples = 10;
23 | int rand_seed = 0;
24 | int not_occ_count = 0;
25 | int total_count = 0;
26 | quat correction_quat = quat(cos45, sin45, 0, 0);
27 | for (int i = 0; i < n_samples; i++)
28 | {
29 | vec3 sample_dir = rand3_near(depth_map_tex_coord, max_angle_shift, rand_seed);
30 | sample_dir = quat_apply(correction_quat, sample_dir);
31 |
32 | float sample_depth = max(texture(samplerCube(light.depth_map_handle), sample_dir).r, 0.0);
33 | sample_depth *= light.coverage;
34 |
35 | not_occ_count += (sample_depth > self_depth ? 1 : 0);
36 | total_count += 1;
37 | }
38 | return 1.0*not_occ_count/total_count;
39 | }
40 |
41 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/DirLight_depth/DirLight_depth.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in VertexOut
4 | {
5 | vec4 color;
6 | vec4 back_color;
7 | vec3 tex_coord;
8 | flat int visible;
9 | } fs_in;
10 |
11 | #include "../../include/InternalMaterial.glsl"
12 |
13 | uniform Material material;
14 | uniform Material back_material;
15 |
16 | void main()
17 | {
18 | if (fs_in.visible == 0)
19 | {
20 | discard;
21 | }
22 |
23 | InternalMaterial internal_material;
24 |
25 | if (gl_FrontFacing)
26 | {
27 | internal_material = fetch_internal_material(fs_in.color, material, fs_in.tex_coord.st);
28 | }
29 | else
30 | {
31 | internal_material = fetch_internal_material(fs_in.back_color, back_material, fs_in.tex_coord.st);
32 | }
33 |
34 | if (internal_material.opacity < 1E-6)
35 | {
36 | discard;
37 | }
38 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/DirLight_depth/DirLight_depth.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | layout (triangles, invocations=CSM_LEVELS) in;
9 | layout (triangle_strip, max_vertices=3) out;
10 |
11 | in VertexOut
12 | {
13 | vec4 color;
14 | vec4 back_color;
15 | vec3 tex_coord;
16 | flat int visible;
17 | } gs_in[];
18 |
19 | out VertexOut
20 | {
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/DirLight.glsl"
29 | #include "../../Lights/DirLight_shadow_mapping.glsl"
30 |
31 | uniform DirLight dir_light;
32 | uniform Camera camera;
33 |
34 | void main()
35 | {
36 | vec3 v1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
37 | vec3 v2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
38 | vec3 face_world_normal = normalize(cross(v1, v2));
39 |
40 | gl_Layer = gl_InvocationID;
41 | for (int i = 0; i < 3; i++)
42 | {
43 | vec3 world_pos = gl_in[i].gl_Position.xyz;
44 | gs_out.visible = gs_in[i].visible;
45 | gs_out.color = gs_in[i].color;
46 | gs_out.back_color = gs_in[i].back_color;
47 | gs_out.tex_coord = gs_in[i].tex_coord;
48 |
49 | gl_Position = world_to_lightNDC(dir_light, camera, gl_InvocationID, world_pos);
50 | EmitVertex();
51 | }
52 |
53 | EndPrimitive();
54 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/DirLight_depth/DirLight_depth.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | layout (location = 0) in vec3 position;
9 | layout (location = 1) in vec3 tex_coord;
10 | layout (location = 2) in vec4 color;
11 | layout (location = 3) in vec4 back_color;
12 | layout (location = 4) in vec4 affine_transform_row0;
13 | layout (location = 5) in vec4 affine_transform_row1;
14 | layout (location = 6) in vec4 affine_transform_row2;
15 | layout (location = 7) in int visible;
16 |
17 | out VertexOut
18 | {
19 | vec4 color;
20 | vec4 back_color;
21 | vec3 tex_coord;
22 | flat int visible;
23 | } vs_out;
24 |
25 | #include "../../include/transform.glsl"
26 |
27 | void main()
28 | {
29 | mat4 transform = transpose(mat4(
30 | affine_transform_row0,
31 | affine_transform_row1,
32 | affine_transform_row2,
33 | vec4(0, 0, 0, 1)
34 | ));
35 |
36 | vec3 world_pos = transform_apply(transform, position);
37 | gl_Position = vec4(world_pos, 1);
38 |
39 | vs_out.visible = visible;
40 | vs_out.color = color;
41 | vs_out.back_color = back_color;
42 | vs_out.tex_coord = tex_coord;
43 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/DirLight_depth/DirLight_depth_lines.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | layout (lines, invocations=CSM_LEVELS) in;
9 | layout (line_strip, max_vertices=2) out;
10 |
11 | in VertexOut
12 | {
13 | vec4 color;
14 | vec4 back_color;
15 | vec3 tex_coord;
16 | flat int visible;
17 | } gs_in[];
18 |
19 | out VertexOut
20 | {
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/DirLight_shadow_mapping.glsl"
29 |
30 | uniform DirLight dir_light;
31 | uniform Camera camera;
32 |
33 | void main()
34 | {
35 | gl_Layer = gl_InvocationID;
36 | for (int i = 0; i < 2; i++)
37 | {
38 | gs_out.visible = gs_in[i].visible;
39 | gs_out.color = gs_in[i].color;
40 | gs_out.back_color = gs_in[i].back_color;
41 | gs_out.tex_coord = gs_in[i].tex_coord;
42 |
43 | gl_Position = world_to_lightNDC(dir_light, camera, gl_InvocationID, gl_in[i].gl_Position.xyz);
44 | EmitVertex();
45 | }
46 | EndPrimitive();
47 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/DirLight_depth/DirLight_depth_points.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | layout (points, invocations=CSM_LEVELS) in;
9 | layout (points, max_vertices=1) out;
10 |
11 | in VertexOut
12 | {
13 | vec4 color;
14 | vec4 back_color;
15 | vec3 tex_coord;
16 | flat int visible;
17 | } gs_in[];
18 |
19 | out VertexOut
20 | {
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/DirLight_shadow_mapping.glsl"
29 |
30 | uniform DirLight dir_light;
31 | uniform Camera camera;
32 |
33 | void main()
34 | {
35 | gl_Layer = gl_InvocationID;
36 |
37 | gs_out.visible = gs_in[0].visible;
38 | gs_out.color = gs_in[0].color;
39 | gs_out.back_color = gs_in[0].back_color;
40 | gs_out.tex_coord = gs_in[0].tex_coord;
41 |
42 | gl_Position = world_to_lightNDC(dir_light, camera, gl_InvocationID, gl_in[0].gl_Position.xyz);
43 | EmitVertex();
44 | EndPrimitive();
45 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/OIT_blend.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | #include "../include/OIT.glsl"
7 |
8 | uniform sampler2D accum_map;
9 | uniform sampler2D reveal_map;
10 |
11 | void main()
12 | {
13 | vec4 accum = texture(accum_map, tex_coord);
14 | float reveal = texture(reveal_map, tex_coord).r;
15 | frag_color = blend_composite(accum, reveal);
16 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/PointLight_depth/PointLight_depth.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | in GeometryOut
8 | {
9 | vec3 world_pos;
10 | vec4 color;
11 | vec4 back_color;
12 | vec3 tex_coord;
13 | flat int visible;
14 | } fs_in;
15 |
16 | #include "../../Lights/PointLight.glsl"
17 | #include "../../include/InternalMaterial.glsl"
18 |
19 | uniform PointLight point_light;
20 | uniform Material material;
21 | uniform Material back_material;
22 |
23 | void main()
24 | {
25 | if (fs_in.visible == 0)
26 | {
27 | discard;
28 | }
29 |
30 | InternalMaterial internal_material;
31 | if (gl_FrontFacing)
32 | {
33 | internal_material = fetch_internal_material(
34 | fs_in.color, material, fs_in.tex_coord.st
35 | );
36 | }
37 | else
38 | {
39 | internal_material = fetch_internal_material(
40 | fs_in.back_color, back_material, fs_in.tex_coord.st
41 | );
42 | }
43 |
44 | if (internal_material.opacity < 1E-6)
45 | {
46 | discard;
47 | }
48 |
49 | float distance_to_light = length(point_light.abs_position - fs_in.world_pos);
50 | gl_FragDepth = distance_to_light / point_light.coverage;
51 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/PointLight_depth/PointLight_depth.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (triangles, invocations=6) in;
8 | layout (triangle_strip, max_vertices=3) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/PointLight.glsl"
29 |
30 | uniform PointLight point_light;
31 |
32 | void main()
33 | {
34 | vec3 v1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
35 | vec3 v2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
36 | vec3 face_world_normal = normalize(cross(v1, v2));
37 |
38 | gl_Layer = gl_InvocationID;
39 |
40 | Camera camera = cube_camera(gl_InvocationID, point_light.abs_position, 0.1, point_light.coverage);
41 | for (int i = 0; i < 3; i++)
42 | {
43 | gs_out.world_pos = gl_in[i].gl_Position.xyz;
44 | gs_out.visible = gs_in[i].visible;
45 | gs_out.color = gs_in[i].color;
46 | gs_out.back_color = gs_in[i].back_color;
47 | gs_out.tex_coord = gs_in[i].tex_coord;
48 |
49 | gl_Position = Camera_project(camera, gs_out.world_pos);
50 | EmitVertex();
51 | }
52 |
53 | EndPrimitive();
54 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/PointLight_depth/PointLight_depth.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | layout (location = 0) in vec3 position;
6 | layout (location = 1) in vec3 tex_coord;
7 | layout (location = 2) in vec4 color;
8 | layout (location = 3) in vec4 back_color;
9 |
10 | // instance
11 | layout (location = 4) in vec4 affine_transform_row0;
12 | layout (location = 5) in vec4 affine_transform_row1;
13 | layout (location = 6) in vec4 affine_transform_row2;
14 | layout (location = 7) in int visible;
15 |
16 | out VertexOut
17 | {
18 | vec4 color;
19 | vec4 back_color;
20 | vec3 tex_coord;
21 | flat int visible;
22 | } vs_out;
23 |
24 | #include "../../include/transform.glsl"
25 |
26 | void main()
27 | {
28 | mat4 transform = transpose(mat4(
29 | affine_transform_row0,
30 | affine_transform_row1,
31 | affine_transform_row2,
32 | vec4(0, 0, 0, 1)
33 | ));
34 |
35 | vec3 world_pos = transform_apply(transform, position);
36 | gl_Position = vec4(world_pos, 1);
37 |
38 | vs_out.visible = visible;
39 | vs_out.color = color;
40 | vs_out.back_color = back_color;
41 | vs_out.tex_coord = tex_coord;
42 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/PointLight_depth/PointLight_depth_lines.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (lines, invocations=6) in;
8 | layout (line_strip, max_vertices=2) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/PointLight.glsl"
29 |
30 | uniform PointLight point_light;
31 |
32 | void main()
33 | {
34 | gl_Layer = gl_InvocationID;
35 | Camera camera = cube_camera(gl_InvocationID, point_light.abs_position, 0.1, point_light.coverage);
36 | for (int i = 0; i < 2; i++)
37 | {
38 | gs_out.world_pos = gl_in[i].gl_Position.xyz;
39 | gs_out.visible = gs_in[i].visible;
40 | gs_out.color = gs_in[i].color;
41 | gs_out.back_color = gs_in[i].back_color;
42 | gs_out.tex_coord = gs_in[i].tex_coord;
43 |
44 | gl_Position = Camera_project(camera, gs_out.world_pos);
45 | EmitVertex();
46 | }
47 | EndPrimitive();
48 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/PointLight_depth/PointLight_depth_points.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (points, invocations=6) in;
8 | layout (points, max_vertices=1) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/PointLight.glsl"
29 |
30 | uniform PointLight point_light;
31 |
32 | void main()
33 | {
34 | gl_Layer = gl_InvocationID;
35 | Camera camera = cube_camera(gl_InvocationID, point_light.abs_position, 0.1, point_light.coverage);
36 | gs_out.world_pos = gl_in[0].gl_Position.xyz;
37 | gs_out.visible = gs_in[0].visible;
38 | gs_out.color = gs_in[0].color;
39 | gs_out.back_color = gs_in[0].back_color;
40 | gs_out.tex_coord = gs_in[0].tex_coord;
41 |
42 | gl_Position = Camera_project(camera, gs_out.world_pos);
43 | EmitVertex();
44 | EndPrimitive();
45 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/SpotLight_depth/SpotLight_depth.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | in GeometryOut
8 | {
9 | vec3 world_pos;
10 | vec4 color;
11 | vec4 back_color;
12 | vec3 tex_coord;
13 | flat int visible;
14 | } fs_in;
15 |
16 | #include "../../Lights/SpotLight.glsl"
17 | #include "../../include/InternalMaterial.glsl"
18 |
19 | uniform SpotLight spot_light;
20 | uniform Material material;
21 | uniform Material back_material;
22 |
23 | void main()
24 | {
25 | if (fs_in.visible == 0)
26 | {
27 | discard;
28 | }
29 |
30 | InternalMaterial internal_material;
31 | if (gl_FrontFacing)
32 | {
33 | internal_material = fetch_internal_material(fs_in.color, material, fs_in.tex_coord.st);
34 | }
35 | else
36 | {
37 | internal_material = fetch_internal_material(fs_in.back_color, back_material, fs_in.tex_coord.st);
38 | }
39 |
40 | if (internal_material.opacity < 1E-6)
41 | {
42 | discard;
43 | }
44 |
45 | float distance_to_light = length(spot_light.abs_position - fs_in.world_pos);
46 | gl_FragDepth = distance_to_light / spot_light.coverage;
47 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/SpotLight_depth/SpotLight_depth.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (triangles, invocations=6) in;
8 | layout (triangle_strip, max_vertices=3) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/SpotLight.glsl"
29 |
30 | uniform SpotLight spot_light;
31 |
32 | void main()
33 | {
34 | vec3 v1 = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz;
35 | vec3 v2 = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz;
36 | vec3 face_world_normal = normalize(cross(v1, v2));
37 |
38 | gl_Layer = gl_InvocationID;
39 | Camera camera = cube_camera(gl_InvocationID, spot_light.abs_position, 0.1, spot_light.coverage);
40 | for (int i = 0; i < 3; i++)
41 | {
42 | gs_out.world_pos = gl_in[i].gl_Position.xyz;
43 | gs_out.visible = gs_in[i].visible;
44 | gs_out.color = gs_in[i].color;
45 | gs_out.back_color = gs_in[i].back_color;
46 | gs_out.tex_coord = gs_in[i].tex_coord;
47 |
48 | gl_Position = Camera_project(camera, gs_out.world_pos);
49 | EmitVertex();
50 | }
51 |
52 | EndPrimitive();
53 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/SpotLight_depth/SpotLight_depth_lines.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (lines, invocations=6) in;
8 | layout (line_strip, max_vertices=2) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/SpotLight.glsl"
29 |
30 | uniform SpotLight spot_light;
31 |
32 | void main()
33 | {
34 | gl_Layer = gl_InvocationID;
35 | Camera camera = cube_camera(gl_InvocationID, spot_light.abs_position, 0.1, spot_light.coverage);
36 | for (int i = 0; i < 2; i++)
37 | {
38 | gs_out.world_pos = gl_in[i].gl_Position.xyz;
39 | gs_out.visible = gs_in[i].visible;
40 | gs_out.color = gs_in[i].color;
41 | gs_out.back_color = gs_in[i].back_color;
42 | gs_out.tex_coord = gs_in[i].tex_coord;
43 |
44 | gl_Position = Camera_project(camera, gs_out.world_pos);
45 | EmitVertex();
46 | }
47 | EndPrimitive();
48 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/SpotLight_depth/SpotLight_depth_points.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | layout (points, invocations=6) in;
8 | layout (points, max_vertices=1) out;
9 |
10 | in VertexOut
11 | {
12 | vec4 color;
13 | vec4 back_color;
14 | vec3 tex_coord;
15 | flat int visible;
16 | } gs_in[];
17 |
18 | out GeometryOut
19 | {
20 | vec3 world_pos;
21 | vec4 color;
22 | vec4 back_color;
23 | vec3 tex_coord;
24 | flat int visible;
25 | } gs_out;
26 |
27 | #include "../../include/Camera.glsl"
28 | #include "../../Lights/SpotLight.glsl"
29 |
30 | uniform SpotLight spot_light;
31 |
32 | void main()
33 | {
34 | gl_Layer = gl_InvocationID;
35 | Camera camera = cube_camera(gl_InvocationID, spot_light.abs_position, 0.1, spot_light.coverage);
36 | gs_out.world_pos = gl_in[0].gl_Position.xyz;
37 | gs_out.visible = gs_in[0].visible;
38 | gs_out.color = gs_in[0].color;
39 | gs_out.back_color = gs_in[0].back_color;
40 | gs_out.tex_coord = gs_in[0].tex_coord;
41 |
42 | gl_Position = Camera_project(camera, gs_out.world_pos);
43 | EmitVertex();
44 | EndPrimitive();
45 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/deferred_rendering/deferred_rendering.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | in vec2 tex_coord;
9 | out vec4 out_color;
10 |
11 | #include "../../include/shading_all.glsl"
12 | #include "read_from_gbuffer.glsl"
13 |
14 | uniform sampler2D world_pos_and_alpha_map;
15 | uniform sampler2D world_normal_and_emission_r_map;
16 | uniform sampler2D ambient_and_emission_g_map;
17 | uniform sampler2D diffuse_or_base_color_and_emission_b_map;
18 | uniform sampler2D specular_and_shininess_map;
19 | uniform sampler2D reflection_map;
20 | uniform sampler2D env_center_and_mixed_value_map;
21 | uniform usampler2D mixed_uint_map;
22 | uniform Camera camera;
23 | uniform Background background;
24 |
25 | #if USE_FOG
26 | uniform Fog fog;
27 | #endif
28 |
29 | void main()
30 | {
31 | PostShadingInfo shading_info = read_from_gbuffer(camera,
32 | world_pos_and_alpha_map, world_normal_and_emission_r_map,
33 | ambient_and_emission_g_map, diffuse_or_base_color_and_emission_b_map,
34 | specular_and_shininess_map, reflection_map,
35 | env_center_and_mixed_value_map, mixed_uint_map, tex_coord
36 | );
37 |
38 | out_color = post_shading_all(camera, camera, background
39 | #if USE_FOG
40 | , fog
41 | #endif
42 | , shading_info
43 | );
44 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/deferred_rendering/draw_points_to_gbuffer.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 |
7 | in VertexOut
8 | {
9 | mat4 affine_transform;
10 | vec3 world_pos;
11 | mat3 world_TBN;
12 | vec3 tex_coord;
13 | vec4 color;
14 | flat int visible;
15 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
16 | flat uvec2 env_map_handle;
17 | #endif
18 | } fs_in;
19 |
20 | layout(location=3) out vec4 world_pos_and_alpha;
21 | layout(location=4) out vec4 world_normal_and_emission_r;
22 | layout(location=2) out vec4 ambient_and_emission_g;
23 | layout(location=0) out vec4 base_color_and_emission_b;
24 | layout(location=1) out vec4 specular_and_shininess;
25 | layout(location=5) out vec4 reflection;
26 | layout(location=6) out vec4 env_center_and_mixed_value;
27 | layout(location=7) out uvec4 mixed_uint;
28 |
29 | #include "../../include/InternalMaterial.glsl"
30 | #include "../../include/parallax_mapping.glsl"
31 | #include "../../include/math.glsl"
32 | #include "../../include/transform.glsl"
33 | #include "write_to_gbuffer.glsl"
34 |
35 | uniform Camera camera;
36 | uniform Material material;
37 | uniform vec3 mesh_center;
38 |
39 | void main()
40 | {
41 | if (fs_in.visible == 0)
42 | {
43 | discard;
44 | }
45 |
46 | vec2 tex_coord = fs_in.tex_coord.st;
47 | mat3 world_TBN = fs_in.world_TBN;
48 | vec3 world_pos = fs_in.world_pos;
49 | vec3 env_center = transform_apply(fs_in.affine_transform, mesh_center);
50 | change_geometry(camera, material, tex_coord, world_TBN, world_pos);
51 | InternalMaterial internal_material = fetch_internal_material(fs_in.color, material, tex_coord);
52 |
53 | write_to_gbuffer(
54 | internal_material, world_pos, world_TBN[2], env_center,
55 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
56 | fs_in.env_map_handle,
57 | #endif
58 | false,
59 | world_pos_and_alpha, world_normal_and_emission_r, ambient_and_emission_g,
60 | base_color_and_emission_b, specular_and_shininess,
61 | reflection, env_center_and_mixed_value, mixed_uint
62 | );
63 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_frame.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | uniform sampler2D screen_image;
9 | uniform sampler2DArray screen_image_array;
10 | uniform int layer;
11 | uniform int index;
12 | uniform bool gray;
13 | uniform bool invert;
14 |
15 | void main()
16 | {
17 | if (layer < 0)
18 | frag_color = max(texture(screen_image, tex_coord), 0.0);
19 | else
20 | frag_color = max(texture(screen_image_array, vec3(tex_coord, layer)), 0.0);
21 |
22 | if (gray)
23 | frag_color = vec4(vec3(frag_color[index]), 1);
24 | if (invert)
25 | frag_color.rgb = 1 - frag_color.rgb;
26 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_geometry/draw_geometry.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | in GeometryOut
9 | {
10 | mat4 affine_transform;
11 | vec3 world_pos;
12 | mat3 world_TBN;
13 | vec3 tex_coord;
14 | vec4 color;
15 | vec4 back_color;
16 | flat int visible;
17 | } fs_in;
18 |
19 | layout(location=3) out vec3 world_pos;
20 | layout(location=4) out vec3 world_normal;
21 |
22 | #include "../../include/InternalMaterial.glsl"
23 | #include "../../include/shading_all.glsl"
24 |
25 | uniform Material material;
26 | uniform Material back_material;
27 | uniform Camera camera;
28 |
29 | void main()
30 | {
31 | if (fs_in.visible == 0)
32 | {
33 | discard;
34 | }
35 |
36 | vec2 tex_coord = fs_in.tex_coord.st;
37 | mat3 world_TBN = fs_in.world_TBN;
38 | world_pos = fs_in.world_pos;
39 | InternalMaterial internal_material;
40 |
41 | if (gl_FrontFacing)
42 | {
43 | change_geometry(camera, material, tex_coord, world_TBN, world_pos);
44 | if (hasnan(world_TBN[2]) || length(world_TBN[2]) < 1E-6)
45 | {
46 | discard;
47 | }
48 |
49 | internal_material = fetch_internal_material(fs_in.color, material, tex_coord);
50 | }
51 | else
52 | {
53 | change_geometry(camera, back_material, tex_coord, world_TBN, world_pos);
54 | if (hasnan(world_TBN[2]) || length(world_TBN[2]) < 1E-6)
55 | {
56 | discard;
57 | }
58 |
59 | internal_material = fetch_internal_material(fs_in.back_color, back_material, tex_coord);
60 | }
61 |
62 | if (internal_material.opacity < 1E-6)
63 | {
64 | discard;
65 | }
66 |
67 | world_normal = world_TBN[2];
68 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_geometry/draw_geometry.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | // vertex
4 | layout (location = 0) in vec3 position;
5 | layout (location = 1) in vec3 tangent;
6 | layout (location = 2) in vec3 bitangent;
7 | layout (location = 3) in vec3 normal;
8 | layout (location = 4) in vec3 tex_coord;
9 | layout (location = 5) in vec4 color;
10 | layout (location = 6) in vec4 back_color;
11 |
12 | // instance
13 | layout (location = 7) in vec4 affine_transform_row0;
14 | layout (location = 8) in vec4 affine_transform_row1;
15 | layout (location = 9) in vec4 affine_transform_row2;
16 | layout (location = 10) in int visible;
17 |
18 | out VertexOut
19 | {
20 | mat4 affine_transform;
21 | mat3 world_TBN;
22 | vec3 tex_coord;
23 | vec3 back_tex_coord;
24 | vec4 color;
25 | vec4 back_color;
26 | flat int visible;
27 | } vs_out;
28 |
29 | #include "../../include/transform.glsl"
30 | #include "../../include/tex_coord.glsl"
31 | #include "../../include/Camera.glsl"
32 | #include "../../include/Material.glsl"
33 |
34 | uniform Camera camera;
35 | uniform Material material;
36 | uniform Material back_material;
37 |
38 | void main()
39 | {
40 | mat4 transform = transpose(mat4(
41 | affine_transform_row0,
42 | affine_transform_row1,
43 | affine_transform_row2,
44 | vec4(0, 0, 0, 1)
45 | ));
46 |
47 | vs_out.affine_transform = transform;
48 | vs_out.color = color;
49 | vs_out.back_color = back_color;
50 | vs_out.visible = visible;
51 | vs_out.world_TBN = transform_apply_to_TBN(transform, mat3(tangent, bitangent, normal));
52 | transform_tex_coord(material, back_material, tex_coord, vs_out.tex_coord, vs_out.back_tex_coord);
53 |
54 | gl_Position = vec4(transform_apply(transform, position), 1);
55 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_geometry/draw_geometry_lines.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : enable
7 |
8 | // vertex
9 | layout (location = 0) in vec3 position;
10 | layout (location = 1) in vec3 bitangent;
11 | layout (location = 2) in vec3 tex_coord;
12 | layout (location = 3) in vec4 color;
13 |
14 | // instance
15 | layout (location = 4) in vec4 affine_transform_row0;
16 | layout (location = 5) in vec4 affine_transform_row1;
17 | layout (location = 6) in vec4 affine_transform_row2;
18 | layout (location = 8) in int visible;
19 |
20 | out VertexOut
21 | {
22 | mat4 affine_transform;
23 | vec3 world_pos;
24 | vec3 world_normal;
25 | vec3 tex_coord;
26 | vec4 color;
27 | flat int visible;
28 | } vs_out;
29 |
30 | #include "../../include/transform.glsl"
31 | #include "../../include/Camera.glsl"
32 |
33 | uniform Camera camera;
34 |
35 | void main()
36 | {
37 | mat4 transform = transpose(mat4(
38 | affine_transform_row0,
39 | affine_transform_row1,
40 | affine_transform_row2,
41 | vec4(0, 0, 0, 1)
42 | ));
43 |
44 | vs_out.affine_transform = transform;
45 | vs_out.color = color;
46 | vs_out.tex_coord = tex_coord;
47 | vs_out.world_pos = transform_apply(transform, position);
48 | vec3 world_bitangent = mat3(transform) * bitangent;
49 | vec3 to_camera = normalize(camera.abs_position - vs_out.world_pos);
50 | vec3 world_tangent = normalize(cross(world_bitangent, to_camera));
51 | vs_out.world_normal = normalize(cross(world_tangent, world_bitangent));
52 | vs_out.visible = visible;
53 |
54 | gl_Position = Camera_project(camera, vs_out.world_pos);
55 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_geometry/draw_geometry_points.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | in VertexOut
9 | {
10 | mat4 affine_transform;
11 | vec3 world_pos;
12 | vec3 world_normal;
13 | vec3 tex_coord;
14 | vec4 color;
15 | flat int visible;
16 | } fs_in;
17 |
18 | layout(location=3) out vec3 world_pos;
19 | layout(location=4) out vec3 world_normal;
20 |
21 | #include "../../include/InternalMaterial.glsl"
22 | #include "../../include/Material.glsl"
23 | #include "../../include/Camera.glsl"
24 |
25 | uniform Material material;
26 | uniform Camera camera;
27 |
28 | void main()
29 | {
30 | if (fs_in.visible == 0)
31 | {
32 | discard;
33 | }
34 |
35 | InternalMaterial internal_material =
36 | fetch_internal_material(fs_in.color, material, fs_in.tex_coord.st);
37 |
38 | if (internal_material.opacity < 1E-6)
39 | {
40 | discard;
41 | }
42 |
43 | world_pos = fs_in.world_pos;
44 | world_normal = fs_in.world_normal;
45 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/draw_geometry/draw_geometry_points.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : enable
7 |
8 | // vertex
9 | layout (location = 0) in vec3 position;
10 | layout (location = 1) in vec3 tex_coord;
11 | layout (location = 2) in vec4 color;
12 |
13 | // instance
14 | layout (location = 3) in vec4 affine_transform_row0;
15 | layout (location = 4) in vec4 affine_transform_row1;
16 | layout (location = 5) in vec4 affine_transform_row2;
17 | layout (location = 6) in int visible;
18 |
19 | out VertexOut
20 | {
21 | mat4 affine_transform;
22 | vec3 world_pos;
23 | vec3 world_normal;
24 | vec3 tex_coord;
25 | vec4 color;
26 | flat int visible;
27 | } vs_out;
28 |
29 | #include "../../include/transform.glsl"
30 | #include "../../include/Camera.glsl"
31 |
32 | uniform Camera camera;
33 |
34 | void main()
35 | {
36 | mat4 transform = transpose(mat4(
37 | affine_transform_row0,
38 | affine_transform_row1,
39 | affine_transform_row2,
40 | vec4(0, 0, 0, 1)
41 | ));
42 |
43 | vs_out.affine_transform = transform;
44 | vs_out.color = color;
45 | vs_out.tex_coord = tex_coord;
46 | vs_out.world_pos = transform_apply(transform, position);
47 | vs_out.world_normal = normalize(camera.abs_position - vs_out.world_pos);
48 | vs_out.visible = visible;
49 |
50 | gl_Position = Camera_project(camera, vs_out.world_pos);
51 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/env_mapping/env_OIT_blend.frag:
--------------------------------------------------------------------------------
1 |
2 | #version 430 core
3 |
4 | in vec2 tex_coord;
5 | out vec4 frag_color;
6 |
7 | #include "../../include/OIT.glsl"
8 | #include "../../include/math.glsl"
9 | #include "../../include/quat.glsl"
10 |
11 | uniform samplerCube opaque_color_map;
12 | uniform samplerCube accum_map;
13 | uniform samplerCube reveal_map;
14 |
15 | void main()
16 | {
17 | float theta = M_PI*(1.5 - 2*tex_coord.x);
18 | float phi = M_PI*(tex_coord.y-0.5);
19 |
20 | vec3 cube_tex_coord;
21 | cube_tex_coord.x = cos(phi)*cos(theta);
22 | cube_tex_coord.y = cos(phi)*sin(theta);
23 | cube_tex_coord.z = sin(phi);
24 | cube_tex_coord = quat_apply(quat(cos45, sin45, 0, 0), cube_tex_coord);
25 |
26 | vec4 opaque_color = max(texture(opaque_color_map, cube_tex_coord), 0.0);
27 | vec4 accum = texture(accum_map, cube_tex_coord);
28 | float reveal = texture(reveal_map, cube_tex_coord).r;
29 | if (hasinf(accum.rgb))
30 | {
31 | accum.rgb = vec3(accum.a);
32 | }
33 |
34 | vec3 transparent_color = accum.rgb / max(accum.a, 1E-6);
35 | float alpha = exp(reveal);
36 | frag_color.rgb = mix(transparent_color, opaque_color.rgb, alpha);
37 | frag_color.a = 1-(1-opaque_color.a)*alpha;
38 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/env_mapping/gen_env_map.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | // vertex
4 | layout (location = 0) in vec3 position;
5 | layout (location = 1) in vec3 tangent;
6 | layout (location = 2) in vec3 bitangent;
7 | layout (location = 3) in vec3 normal;
8 | layout (location = 4) in vec3 tex_coord;
9 | layout (location = 5) in vec4 color;
10 | layout (location = 6) in vec4 back_color;
11 |
12 | // instance
13 | layout (location = 7) in vec4 affine_transform_row0;
14 | layout (location = 8) in vec4 affine_transform_row1;
15 | layout (location = 9) in vec4 affine_transform_row2;
16 |
17 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
18 | layout (location = 10) in uvec2 env_map_handle;
19 | #endif
20 |
21 | layout (location = 11) in int visible;
22 |
23 | out VertexOut
24 | {
25 | mat4 affine_transform;
26 | mat3 world_TBN;
27 | vec3 tex_coord;
28 | vec3 back_tex_coord;
29 | vec4 color;
30 | vec4 back_color;
31 |
32 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
33 | flat uvec2 env_map_handle;
34 | #endif
35 |
36 | flat int visible;
37 | } vs_out;
38 |
39 | #include "../../include/transform.glsl"
40 | #include "../../include/tex_coord.glsl"
41 | #include "../../include/Material.glsl"
42 |
43 | uniform Material material;
44 | uniform Material back_material;
45 |
46 | void main()
47 | {
48 | mat4 transform = transpose(mat4(
49 | affine_transform_row0,
50 | affine_transform_row1,
51 | affine_transform_row2,
52 | vec4(0, 0, 0, 1)
53 | ));
54 |
55 | vs_out.affine_transform = transform;
56 | vs_out.color = color;
57 | vs_out.back_color = back_color;
58 | vs_out.world_TBN = transform_apply_to_TBN(transform, mat3(tangent, bitangent, normal));
59 |
60 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
61 | vs_out.env_map_handle = env_map_handle;
62 | #endif
63 |
64 | transform_tex_coord(material, back_material, tex_coord, vs_out.tex_coord, vs_out.back_tex_coord);
65 | vs_out.visible = visible;
66 |
67 | gl_Position = vec4(transform_apply(transform, position), 1);
68 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/env_mapping/gen_env_map_points.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | in GeometryOut
9 | {
10 | mat4 affine_transform;
11 | vec3 world_pos;
12 | mat3 world_TBN;
13 | vec3 tex_coord;
14 | vec4 color;
15 | flat int visible;
16 | } fs_in;
17 |
18 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
19 | in flat uvec2 env_map_handle;
20 | #endif
21 |
22 | layout(location=0) out vec4 out_color;
23 | layout(location=1) out vec4 accum;
24 | layout(location=2) out float reveal;
25 |
26 | #include "../../include/Camera.glsl"
27 | #include "../../include/Material.glsl"
28 | #include "../../include/OIT.glsl"
29 | #include "../../include/fog.glsl"
30 | #include "../../include/shading_all.glsl"
31 |
32 | uniform vec3 view_center;
33 | uniform vec3 mesh_center;
34 | uniform Material material;
35 | uniform bool is_opaque_pass;
36 | uniform Camera CSM_camera;
37 | uniform Background background;
38 |
39 | #if USE_FOG
40 | uniform Fog fog;
41 | #endif
42 |
43 | void main()
44 | {
45 | if (fs_in.visible == 0)
46 | {
47 | discard;
48 | }
49 |
50 | Camera camera = cube_camera(gl_Layer, view_center);
51 |
52 | ShadingInfo shading_info;
53 | shading_info.color = fs_in.color;
54 | #if USE_DYNAMIC_ENV_MAPPING
55 | shading_info.env_map_handle = env_map_handle;
56 | #endif
57 | shading_info.is_opaque_pass = is_opaque_pass;
58 | shading_info.is_sphere = false;
59 | shading_info.world_TBN = fs_in.world_TBN;
60 | shading_info.world_pos = fs_in.world_pos;
61 | shading_info.tex_coord = fs_in.tex_coord.st;
62 | shading_info.affine_transform = fs_in.affine_transform;
63 | shading_info.mesh_center = mesh_center;
64 |
65 | out_color = shading_all(camera, CSM_camera, background, material
66 | #if USE_FOG
67 | , fog
68 | #endif
69 | , shading_info);
70 |
71 | if (!is_opaque_pass && out_color.a < 1 - 1E-6)
72 | {
73 | vec3 view_pos = world_to_view(camera, fs_in.world_pos);
74 | get_OIT_info(out_color, view_pos.y, accum, reveal);
75 | out_color = vec4(0);
76 | }
77 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/env_mapping/gen_env_map_points.geom:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | layout (points, invocations=6) in;
9 | layout (points, max_vertices=1) out;
10 |
11 | in VertexOut
12 | {
13 | mat4 affine_transform;
14 | vec3 tex_coord;
15 | vec4 color;
16 |
17 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
18 | flat uvec2 env_map_handle;
19 | #endif
20 |
21 | flat int visible;
22 | } gs_in[];
23 |
24 | out GeometryOut
25 | {
26 | mat4 affine_transform;
27 | vec3 world_pos;
28 | vec3 world_normal;
29 | vec3 tex_coord;
30 | vec4 color;
31 | flat int visible;
32 | } gs_out;
33 |
34 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
35 | out flat uvec2 env_map_handle;
36 | #endif
37 |
38 | #include "../../include/transform.glsl"
39 | #include "../../include/Camera.glsl"
40 | #include "../../include/InternalMaterial.glsl"
41 | #include "../../Lights/Lights_lighting.glsl"
42 |
43 | uniform vec3 view_center;
44 | uniform Material material;
45 | uniform Camera CSM_camera;
46 |
47 | void main()
48 | {
49 | gl_Layer = gl_InvocationID;
50 | Camera camera = cube_camera(gl_InvocationID, view_center);
51 |
52 | gs_out.affine_transform = gs_in[0].affine_transform;
53 | gs_out.world_pos = gl_in[0].gl_Position.xyz;
54 | gs_out.world_normal = normalize(camera.abs_position - gs_out.world_pos);
55 | gs_out.tex_coord = gs_in[0].tex_coord;
56 | gs_out.color = gs_in[0].color;
57 | gs_out.visible = gs_in[0].visible;
58 |
59 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
60 | env_map_handle = gs_in[0].env_map_handle;
61 | #endif
62 |
63 | #if USE_SHADING_MODEL_FLAT || USE_SHADING_MODEL_GOURAUD
64 | if (material.shading_model == SHADING_MODEL_FLAT ||
65 | material.shading_model == SHADING_MODEL_GOURAUD)
66 | {
67 | InternalMaterial internal_material = fetch_internal_material(gs_in[0].color, material, gs_in[0].tex_coord.st);
68 | gs_out.color = vec4(lighting(internal_material, CSM_camera, camera.abs_position, gs_out.world_pos, gs_out.world_normal), 1.0);
69 | }
70 | #endif
71 |
72 | gl_Position = Camera_project(camera, gs_out.world_pos);
73 | EmitVertex();
74 | EndPrimitive();
75 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/env_mapping/gen_env_map_points.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | // vertex
4 | layout (location = 0) in vec3 position;
5 | layout (location = 1) in vec3 tex_coord;
6 | layout (location = 2) in vec4 color;
7 |
8 | // instance
9 | layout (location = 3) in vec4 affine_transform_row0;
10 | layout (location = 4) in vec4 affine_transform_row1;
11 | layout (location = 5) in vec4 affine_transform_row2;
12 |
13 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
14 | layout (location = 6) in uvec2 env_map_handle;
15 | #endif
16 |
17 | layout (location = 7) in int visible;
18 |
19 | out VertexOut
20 | {
21 | mat4 affine_transform;
22 | vec3 tex_coord;
23 | vec4 color;
24 |
25 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
26 | flat uvec2 env_map_handle;
27 | #endif
28 |
29 | flat int visible;
30 | } vs_out;
31 |
32 | #include "../../include/transform.glsl"
33 |
34 | void main()
35 | {
36 | mat4 transform = transpose(mat4(
37 | affine_transform_row0,
38 | affine_transform_row1,
39 | affine_transform_row2,
40 | vec4(0, 0, 0, 1)
41 | ));
42 |
43 | vec3 world_pos = transform_apply(transform, position);
44 | gl_Position = vec4(world_pos, 1);
45 |
46 | vs_out.affine_transform = transform;
47 | vs_out.color = color;
48 | vs_out.tex_coord = tex_coord;
49 |
50 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
51 | vs_out.env_map_handle = env_map_handle;
52 | #endif
53 |
54 | vs_out.visible = visible;
55 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/forward_rendering/forward_draw_points.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : require
7 |
8 | in VertexOut
9 | {
10 | mat4 affine_transform;
11 | vec3 world_pos;
12 | mat3 world_TBN;
13 | vec3 tex_coord;
14 | vec4 color;
15 | flat int visible;
16 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
17 | flat uvec2 env_map_handle;
18 | #endif
19 |
20 | } fs_in;
21 |
22 | layout(location=0) out vec4 out_color;
23 | layout(location=1) out vec4 accum;
24 | layout(location=2) out float reveal;
25 | layout(location=3) out vec3 world_pos;
26 | layout(location=4) out vec3 world_normal;
27 |
28 | #include "../../include/Material.glsl"
29 | #include "../../include/OIT.glsl"
30 | #include "../../include/fog.glsl"
31 | #include "../../include/shading_all.glsl"
32 |
33 | uniform Material material;
34 | uniform Camera camera;
35 | uniform bool is_opaque_pass;
36 | uniform vec3 mesh_center;
37 |
38 | #if USE_FOG
39 | uniform Fog fog;
40 | #endif
41 |
42 | uniform Background background;
43 |
44 | void main()
45 | {
46 | if (fs_in.visible == 0)
47 | {
48 | discard;
49 | }
50 |
51 | ShadingInfo shading_info;
52 | shading_info.color = fs_in.color;
53 | #if USE_DYNAMIC_ENV_MAPPING
54 | shading_info.env_map_handle = fs_in.env_map_handle;
55 | #endif
56 | shading_info.is_opaque_pass = is_opaque_pass;
57 | shading_info.is_sphere = false;
58 | shading_info.world_TBN = fs_in.world_TBN;
59 | shading_info.world_pos = fs_in.world_pos;
60 | shading_info.tex_coord = fs_in.tex_coord.st;
61 | shading_info.affine_transform = fs_in.affine_transform;
62 | shading_info.mesh_center = mesh_center;
63 |
64 | out_color = shading_all(camera, background, material
65 | #if USE_FOG
66 | , fog
67 | #endif
68 | , shading_info);
69 |
70 | if (is_opaque_pass)
71 | {
72 | world_pos = shading_info.world_pos;
73 | world_normal = shading_info.world_TBN[2];
74 | }
75 | else if (out_color.a < 1 - 1E-6)
76 | {
77 | vec3 view_pos = world_to_view(camera, fs_in.world_pos);
78 | get_OIT_info(out_color, view_pos.y, accum, reveal);
79 | out_color = vec4(0);
80 | }
81 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/forward_rendering/forward_draw_points.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #if USE_BINDLESS_TEXTURE
4 | #extension GL_ARB_bindless_texture : require
5 | #endif
6 | #extension GL_EXT_texture_array : enable
7 |
8 | // vertex
9 | layout (location = 0) in vec3 position;
10 | layout (location = 1) in vec3 tex_coord;
11 | layout (location = 2) in vec4 color;
12 |
13 | // instance
14 | layout (location = 3) in vec4 affine_transform_row0;
15 | layout (location = 4) in vec4 affine_transform_row1;
16 | layout (location = 5) in vec4 affine_transform_row2;
17 |
18 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
19 | layout (location = 6) in uvec2 env_map_handle;
20 | #endif
21 |
22 | layout (location = 7) in int visible;
23 |
24 | out VertexOut
25 | {
26 | mat4 affine_transform;
27 | vec3 world_pos;
28 | vec3 world_normal;
29 | vec3 tex_coord;
30 | vec4 color;
31 | flat int visible;
32 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
33 | flat uvec2 env_map_handle;
34 | #endif
35 |
36 | } vs_out;
37 |
38 | #include "../../include/transform.glsl"
39 | #include "../../include/Camera.glsl"
40 | #include "../../include/InternalMaterial.glsl"
41 | #include "../../Lights/Lights_lighting.glsl"
42 |
43 | uniform Camera camera;
44 | uniform Material material;
45 |
46 | void main()
47 | {
48 | mat4 transform = transpose(mat4(
49 | affine_transform_row0,
50 | affine_transform_row1,
51 | affine_transform_row2,
52 | vec4(0, 0, 0, 1)
53 | ));
54 |
55 | vs_out.affine_transform = transform;
56 | vs_out.color = color;
57 | vs_out.tex_coord = tex_coord;
58 | vs_out.world_pos = transform_apply(transform, position);
59 | vs_out.world_normal = normalize(camera.abs_position - vs_out.world_pos);
60 |
61 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
62 | vs_out.env_map_handle = env_map_handle;
63 | #endif
64 |
65 | vs_out.visible = visible;
66 | gl_Position = Camera_project(camera, vs_out.world_pos);
67 |
68 | #if USE_SHADING_MODEL_FLAT || USE_SHADING_MODEL_GOURAUD
69 | if (material.shading_model == SHADING_MODEL_FLAT ||
70 | material.shading_model == SHADING_MODEL_GOURAUD)
71 | {
72 | InternalMaterial internal_material = fetch_internal_material(color, material, tex_coord.st);
73 | vs_out.color = vec4(lighting(internal_material, camera, camera.abs_position, vs_out.world_pos, vs_out.world_normal), 1.0);
74 | }
75 | #endif
76 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/forward_rendering/forward_rendering.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | // vertex
4 | layout (location = 0) in vec3 position;
5 | layout (location = 1) in vec3 tangent;
6 | layout (location = 2) in vec3 bitangent;
7 | layout (location = 3) in vec3 normal;
8 | layout (location = 4) in vec3 tex_coord;
9 | layout (location = 5) in vec4 color;
10 | layout (location = 6) in vec4 back_color;
11 |
12 | // instance
13 | layout (location = 7) in vec4 affine_transform_row0;
14 | layout (location = 8) in vec4 affine_transform_row1;
15 | layout (location = 9) in vec4 affine_transform_row2;
16 |
17 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
18 | layout (location = 10) in uvec2 env_map_handle;
19 | #endif
20 |
21 | layout (location = 11) in int visible;
22 |
23 | out VertexOut
24 | {
25 | mat4 affine_transform;
26 | mat3 world_TBN;
27 | vec3 tex_coord;
28 | vec3 back_tex_coord;
29 | vec4 color;
30 | vec4 back_color;
31 |
32 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
33 | flat uvec2 env_map_handle;
34 | #endif
35 |
36 | flat int visible;
37 | } vs_out;
38 |
39 | #include "../../include/transform.glsl"
40 | #include "../../include/Camera.glsl"
41 | #include "../../include/tex_coord.glsl"
42 |
43 | uniform Camera camera;
44 | uniform Material material;
45 | uniform Material back_material;
46 |
47 | void main()
48 | {
49 | mat4 transform = transpose(mat4(
50 | affine_transform_row0,
51 | affine_transform_row1,
52 | affine_transform_row2,
53 | vec4(0, 0, 0, 1)
54 | ));
55 |
56 | vs_out.affine_transform = transform;
57 | vs_out.color = color;
58 | vs_out.back_color = back_color;
59 | vs_out.world_TBN = transform_apply_to_TBN(transform, mat3(tangent, bitangent, normal));
60 |
61 | #if USE_BINDLESS_TEXTURE && USE_DYNAMIC_ENV_MAPPING
62 | vs_out.env_map_handle = env_map_handle;
63 | #endif
64 |
65 | transform_tex_coord(material, back_material, tex_coord, vs_out.tex_coord, vs_out.back_tex_coord);
66 |
67 | vs_out.visible = visible;
68 | gl_Position = vec4(transform_apply(transform, position), 1);
69 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/skybox/skybox.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | layout(location=0) out vec4 frag_color;
4 | layout(location=3) out vec3 world_pos;
5 | layout(location=4) out vec3 world_normal;
6 |
7 | in vec3 tex_coord;
8 | in vec3 view_dir;
9 |
10 | #include "../../include/fog.glsl"
11 | #include "../../include/Camera.glsl"
12 |
13 | uniform samplerCube skybox_map;
14 | uniform float sky_distance;
15 | uniform Camera camera;
16 |
17 | #if USE_FOG
18 | uniform Fog fog;
19 | #endif
20 |
21 | void main()
22 | {
23 | frag_color = max(texture(skybox_map, tex_coord), 0.0);
24 |
25 | #if USE_FOG
26 | frag_color.rgb = fog_apply(fog, frag_color.rgb, sky_distance);
27 | #endif
28 |
29 | world_pos = sky_distance * normalize(view_dir);
30 | world_normal = vec3(0);
31 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/skybox/skybox.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 | layout (location = 0) in vec3 position;
3 |
4 | out vec3 tex_coord;
5 | out vec3 view_dir;
6 |
7 | #include "../../include/Camera.glsl"
8 |
9 | uniform Camera camera;
10 |
11 | void main()
12 | {
13 | tex_coord = position;
14 | vec3 world_dir = quat_apply(quat(cos45, -sin45, 0, 0), position);
15 | view_dir = world_dir_to_view(camera, world_dir);
16 | vec4 NDC = view_to_NDC(camera, view_dir, CAMERA_PROJECTION_PERSPECTIVE);
17 |
18 | gl_Position = NDC.xyww;
19 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/skydome/skydome.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 frag_tex_coord;
4 | in vec3 view_dir;
5 |
6 | layout(location=0) out vec4 frag_color;
7 | layout(location=3) out vec3 world_pos;
8 | layout(location=4) out vec3 world_normal;
9 |
10 | #include "../../include/fog.glsl"
11 | #include "../../include/Camera.glsl"
12 |
13 | uniform sampler2D skydome_map;
14 | uniform float sky_distance;
15 | uniform Camera camera;
16 |
17 | #if USE_FOG
18 | uniform Fog fog;
19 | #endif
20 |
21 | void main()
22 | {
23 | frag_color = max(textureLod(skydome_map, frag_tex_coord, 0), 0.0);
24 |
25 | #if USE_FOG
26 | frag_color.rgb = fog_apply(fog, frag_color.rgb, sky_distance);
27 | #endif
28 |
29 | world_pos = sky_distance * normalize(view_dir);
30 | world_normal = vec3(0);
31 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/Pipelines/skydome/skydome.vert:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | layout (location = 0) in vec3 position;
4 | layout (location = 1) in vec2 tex_coord;
5 |
6 | out vec2 frag_tex_coord;
7 | out vec3 view_dir;
8 |
9 | #include "../../include/Camera.glsl"
10 |
11 | uniform Camera camera;
12 |
13 | void main()
14 | {
15 | frag_tex_coord = tex_coord;
16 | view_dir = world_dir_to_view(camera, position);
17 | vec4 NDC = view_to_NDC(camera, view_dir, CAMERA_PROJECTION_PERSPECTIVE);
18 |
19 | gl_Position = NDC.xyww;
20 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/ACES_tone_mapper.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _ACES_TONE_MAPPER_GLSL_
2 | #define _ACES_TONE_MAPPER_GLSL_
3 |
4 | //=================================================================================================
5 | //
6 | // Baking Lab
7 | // by MJP and David Neubelt
8 | // http://mynameismjp.wordpress.com/
9 | // https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
10 | //
11 | // All code licensed under the MIT license
12 | //
13 | //=================================================================================================
14 |
15 | // The code in this file was originally written by Stephen Hill (@self_shadow), who deserves all
16 | // credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :)
17 |
18 | // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
19 | const mat3 ACESInputMat = mat3(
20 | vec3(0.59719, 0.07600, 0.02840),
21 | vec3(0.35458, 0.90834, 0.13383),
22 | vec3(0.04823, 0.01566, 0.83777)
23 | );
24 |
25 | // ODT_SAT => XYZ => D60_2_D65 => sRGB
26 | const mat3x3 ACESOutputMat = mat3(
27 | vec3(1.60475, -0.10208, -0.00327),
28 | vec3(-0.53108, 1.10813, -0.07276),
29 | vec3(-0.07367, -0.00605, 1.07602)
30 | );
31 |
32 | vec3 RRTAndODTFit(vec3 v)
33 | {
34 | vec3 a = v * (v + 0.0245786) - 0.000090537;
35 | vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;
36 | return a / b;
37 | }
38 |
39 | vec3 ACESFitted(vec3 color)
40 | {
41 | color = ACESInputMat * color;
42 |
43 | // Apply RRT and ODT
44 | color = RRTAndODTFit(color);
45 |
46 | color = ACESOutputMat * color;
47 |
48 | // Clamp to [0, 1]
49 | color = clamp(color, 0.0, 1.0);
50 |
51 | return color;
52 | }
53 |
54 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
55 | {
56 | vec4 result = max(textureLod(screen_image, tex_coord, 0), 0.0);
57 | result.rgb = ACESFitted(result.rgb);
58 | // result.rgb = sin(acos(-1)/2.0*result.rgb);
59 | return result;
60 | }
61 |
62 |
63 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/FXAA.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | #include "../include/FXAA.glsl"
9 |
10 | uniform sampler2D screen_image;
11 |
12 | void main()
13 | {
14 | frag_color = textureFXAA(screen_image, tex_coord);
15 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/FXAA_array.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | #include "../include/FXAA.glsl"
9 |
10 | uniform sampler2DArray screen_image;
11 |
12 | void main()
13 | {
14 | frag_color = textureFXAA(screen_image, vec3(tex_coord, gl_Layer));
15 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/FXAA_cube.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | #include "../include/FXAA.glsl"
9 |
10 | uniform samplerCube screen_image;
11 |
12 | void main()
13 | {
14 | frag_color = textureCubeFaceFXAA(screen_image, tex_coord, gl_Layer);
15 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/bloom_mix.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | uniform sampler2D screen_image;
7 | uniform sampler2D bloom_image;
8 |
9 | void main()
10 | {
11 | vec4 src_color = max(texture(screen_image, tex_coord), 0.0);
12 | vec4 bloom_color = max(texture(bloom_image, tex_coord), 0.0);
13 | frag_color = mix(bloom_color, src_color, 0.9);
14 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/bloom_upsampling.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | uniform float filter_radius;
7 | uniform sampler2D screen_image;
8 |
9 | void main()
10 | {
11 | // The filter kernel is applied with a radius, specified in texture
12 | // coordinates, so that the radius will vary across mip resolutions.
13 | float dx = filter_radius;
14 | float dy = filter_radius;
15 |
16 | // Take 9 samples around current texel:
17 | // a - b - c
18 | // d - e - f
19 | // g - h - i
20 | // === ('e' is the current texel) ===
21 | vec4 a = textureLod(screen_image, vec2(tex_coord.x - dx, tex_coord.y + dy), 0);
22 | vec4 b = textureLod(screen_image, vec2(tex_coord.x, tex_coord.y + dy), 0);
23 | vec4 c = textureLod(screen_image, vec2(tex_coord.x + dx, tex_coord.y + dy), 0);
24 |
25 | vec4 d = textureLod(screen_image, vec2(tex_coord.x - dx, tex_coord.y), 0);
26 | vec4 e = textureLod(screen_image, vec2(tex_coord.x, tex_coord.y), 0);
27 | vec4 f = textureLod(screen_image, vec2(tex_coord.x + dx, tex_coord.y), 0);
28 |
29 | vec4 g = textureLod(screen_image, vec2(tex_coord.x - dx, tex_coord.y - dy), 0);
30 | vec4 h = textureLod(screen_image, vec2(tex_coord.x, tex_coord.y - dy), 0);
31 | vec4 i = textureLod(screen_image, vec2(tex_coord.x + dx, tex_coord.y - dy), 0);
32 |
33 | // Apply weighted distribution, by using a 3x3 tent filter:
34 | // 1 | 1 2 1 |
35 | // -- * | 2 4 2 |
36 | // 16 | 1 2 1 |
37 | frag_color = e*4.0;
38 | frag_color += (b+d+f+h)*2.0;
39 | frag_color += (a+c+g+i);
40 | frag_color *= 1.0 / 16.0;
41 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/exposure_adaptor.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _EXPOSURE_ADAPTOR_GLSL_
2 | #define _EXPOSURE_ADAPTOR_GLSL_
3 |
4 | #include "../include/math.glsl"
5 |
6 | uniform float fps;
7 |
8 | buffer CurrentLuma
9 | {
10 | float current_luma;
11 | };
12 |
13 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
14 | {
15 | vec4 color = max(textureLod(screen_image, tex_coord, 0), 0.0);
16 | ivec2 frag_coord = ivec2(gl_FragCoord.xy);
17 | if (!camera.lens.auto_exposure)
18 | {
19 | if (frag_coord.x == 0 && frag_coord.y == 0)
20 | {
21 | current_luma = pow((1.0/camera.lens.exposure) - 0.5, 2.0);
22 | memoryBarrier();
23 | }
24 |
25 | color.rgb = camera.lens.exposure * color.rgb;
26 | }
27 | else if (!camera.lens.local_exposure)
28 | {
29 | float target_luma = luminance(max(textureLod(screen_image, camera.lens.focus_tex_coord, 6).rgb, 0.0));
30 | float luma = target_luma;
31 | float _current_luma = current_luma;
32 | if (abs(target_luma-current_luma) > 1E-6)
33 | {
34 | if (_current_luma != 0 && camera.lens.exposure_adapt_time > 1E-6)
35 | {
36 | float sgn = sign(target_luma - _current_luma);
37 | float a = log(10)/camera.lens.exposure_adapt_time;
38 | luma = _current_luma + a * (target_luma - _current_luma) / fps;
39 | if (sgn == sign(luma - target_luma))
40 | {
41 | luma = target_luma;
42 | }
43 | }
44 | if (frag_coord.x == 0 && frag_coord.y == 0)
45 | {
46 | current_luma = luma;
47 | memoryBarrier();
48 | }
49 | }
50 |
51 | color.rgb = color.rgb / (0.5 + sqrt(luma));
52 | return color;
53 | }
54 | else
55 | {
56 | float luma = luminance(max(textureLod(screen_image, tex_coord, 7).rgb, 0.0));
57 | color.rgb = color.rgb / (0.5 + sqrt(luma));
58 | }
59 | return color;
60 | }
61 |
62 |
63 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/gauss_blur.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | uniform sampler2D screen_image;
7 | uniform bool horizontal;
8 |
9 | uniform uvec2 kernel_shape;
10 | uniform vec2 sigma;
11 | uniform int channels;
12 |
13 | void main()
14 | {
15 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0);
16 | frag_color = vec4(0);
17 |
18 | if (horizontal)
19 | {
20 | float double_sigma_x2 = 2*sigma.x*sigma.x;
21 | float t = tex_coord.t;
22 | float weight_sum = 0;
23 | for(int j = 0; j < kernel_shape.x; j++)
24 | {
25 | float dj = j - 0.5*(kernel_shape.x-1);
26 | float ds = dj*tex_offset.x;
27 | float s = tex_coord.s + ds;
28 | float weight = exp(-dj*dj/double_sigma_x2);
29 | vec4 current_value = max(textureLod(screen_image, vec2(s, t), 0), 0.0);
30 | if (channels == 1)
31 | {
32 | current_value.gb = current_value.rr;
33 | current_value.a = 1;
34 | }
35 | frag_color += weight * current_value;
36 | weight_sum += weight;
37 | }
38 | frag_color = frag_color / weight_sum;
39 | }
40 | else
41 | {
42 | float double_sigma_y2 = 2*sigma.y*sigma.y;
43 | float s = tex_coord.s;
44 | float weight_sum = 0;
45 | for(int i = 0; i < kernel_shape.y; i++)
46 | {
47 | float di = i - 0.5*(kernel_shape.y-1);
48 | float dt = di*tex_offset.y;
49 | float t = tex_coord.t + dt;
50 | float weight = exp(-di*di/double_sigma_y2);
51 | vec4 current_value = max(textureLod(screen_image, vec2(s, t), 0), 0.0);
52 | if (channels == 1)
53 | {
54 | current_value.gb = current_value.rr;
55 | current_value.a = 1;
56 | }
57 | frag_color += weight * current_value;
58 | weight_sum += weight;
59 | }
60 | frag_color = frag_color / weight_sum;
61 | }
62 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/gauss_blur_array.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | uniform sampler2DArray screen_image;
9 | uniform bool horizontal;
10 |
11 | uniform uvec2 kernel_shape;
12 | uniform vec2 sigma;
13 | uniform int channels;
14 |
15 | void main()
16 | {
17 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0).xy;
18 | frag_color = vec4(0);
19 |
20 | if (horizontal)
21 | {
22 | float double_sigma_x2 = 2*sigma.x*sigma.x;
23 | float t = tex_coord.t;
24 | float weight_sum = 0;
25 | for(int j = 0; j < kernel_shape.x; j++)
26 | {
27 | float d = (j - 0.5*(kernel_shape.x-1))*tex_offset.x;
28 | float s = tex_coord.s + d;
29 | float weight = exp(-d*d/double_sigma_x2);
30 | vec4 current_value = max(texture(screen_image, vec3(s, t, gl_Layer)), 0.0);
31 | if (channels == 1)
32 | {
33 | current_value.gb = current_value.rr;
34 | current_value.a = 1;
35 | }
36 | frag_color += weight * current_value;
37 | weight_sum += weight;
38 | }
39 | frag_color = frag_color / weight_sum;
40 | }
41 | else
42 | {
43 | float double_sigma_y2 = 2*sigma.y*sigma.y;
44 | float s = tex_coord.s;
45 | float weight_sum = 0;
46 | for(int i = 0; i < kernel_shape.y; i++)
47 | {
48 | float d = (i - 0.5*(kernel_shape.y-1))*tex_offset.y;
49 | float t = tex_coord.t + d;
50 | float weight = exp(-d*d/double_sigma_y2);
51 | vec4 current_value = max(texture(screen_image, vec3(s, t, gl_Layer)), 0.0);
52 | if (channels == 1)
53 | {
54 | current_value.gb = current_value.rr;
55 | current_value.a = 1;
56 | }
57 | frag_color += weight * current_value;
58 | weight_sum += weight;
59 | }
60 | frag_color = frag_color / weight_sum;
61 | }
62 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/gauss_blur_cube.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | #include "../include/sampling.glsl"
7 |
8 | uniform samplerCube screen_image;
9 | uniform bool horizontal;
10 |
11 | uniform uvec2 kernel_shape;
12 | uniform vec2 sigma;
13 | uniform int channels;
14 |
15 | void main()
16 | {
17 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0).xy;
18 | frag_color = vec4(0);
19 |
20 | if (horizontal)
21 | {
22 | float double_sigma_x2 = 2*sigma.x*sigma.x;
23 | float t = tex_coord.t;
24 | float weight_sum = 0;
25 | for(int j = 0; j < kernel_shape.x; j++)
26 | {
27 | float d = (j - 0.5*(kernel_shape.x-1))*tex_offset.x;
28 | float s = tex_coord.s + d;
29 | float weight = exp(-d*d/double_sigma_x2);
30 | vec4 current_value = max(textureCubeFace(screen_image, vec2(s, t), gl_Layer), 0.0);
31 | if (channels == 1)
32 | {
33 | current_value.gb = current_value.rr;
34 | current_value.a = 1;
35 | }
36 | frag_color += weight * current_value;
37 | weight_sum += weight;
38 | }
39 | frag_color = frag_color / weight_sum;
40 | }
41 | else
42 | {
43 | float double_sigma_y2 = 2*sigma.y*sigma.y;
44 | float s = tex_coord.s;
45 | float weight_sum = 0;
46 | for(int i = 0; i < kernel_shape.y; i++)
47 | {
48 | float d = (i - 0.5*(kernel_shape.y-1))*tex_offset.y;
49 | float t = tex_coord.t + d;
50 | float weight = exp(-d*d/double_sigma_y2);
51 | vec4 current_value = max(textureCubeFace(screen_image, vec2(s, t), gl_Layer), 0.0);
52 | if (channels == 1)
53 | {
54 | current_value.gb = current_value.rr;
55 | current_value.a = 1;
56 | }
57 | frag_color += weight * current_value;
58 | weight_sum += weight;
59 | }
60 | frag_color = frag_color / weight_sum;
61 | }
62 | }
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/kernel_filter.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | uniform sampler2D screen_image;
7 | uniform int channels;
8 |
9 | buffer Kernel
10 | {
11 | int rows;
12 | int cols;
13 | float data[];
14 | };
15 |
16 | void main()
17 | {
18 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0);
19 | float dx = tex_offset.x;
20 | float dy = tex_offset.y;
21 |
22 | frag_color = vec4(0);
23 | for (int i = 0; i < rows; i++)
24 | {
25 | float t = tex_coord.t + (i - 0.5*(rows-1))*dy;
26 | for (int j = 0; j < cols; j++)
27 | {
28 | float s = tex_coord.s + (j - 0.5*(cols-1))*dx;
29 | vec4 current_value = max(textureLod(screen_image, vec2(s, t), 0), 0.0);
30 | if (channels == 1)
31 | {
32 | current_value.gb = current_value.rr;
33 | current_value.a = 1;
34 | }
35 | frag_color += data[i*cols + j] * current_value;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/kernel_filter_array.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | #extension GL_EXT_texture_array : require
4 |
5 | in vec2 tex_coord;
6 | out vec4 frag_color;
7 |
8 | uniform sampler2DArray screen_image;
9 | uniform int channels;
10 |
11 | buffer Kernel
12 | {
13 | int rows;
14 | int cols;
15 | float data[];
16 | };
17 |
18 | void main()
19 | {
20 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0).xy;
21 | float dx = tex_offset.x;
22 | float dy = tex_offset.y;
23 |
24 | frag_color = vec4(0);
25 | for (int i = 0; i < rows; i++)
26 | {
27 | float t = tex_coord.t + (i - 0.5*(rows-1))*dy;
28 | for (int j = 0; j < cols; j++)
29 | {
30 | float s = tex_coord.s + (j - 0.5*(cols-1))*dx;
31 | vec4 current_value = max(texture(screen_image, vec3(s, t, gl_Layer)), 0.0);
32 | if (channels == 1)
33 | {
34 | current_value.gb = current_value.rr;
35 | current_value.a = 1;
36 | }
37 | frag_color += data[i*cols + j] * current_value;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/kernel_filter_cube.frag:
--------------------------------------------------------------------------------
1 | #version 430 core
2 |
3 | in vec2 tex_coord;
4 | out vec4 frag_color;
5 |
6 | #include "../include/sampling.glsl"
7 |
8 | uniform samplerCube screen_image;
9 | uniform int channels;
10 |
11 | buffer Kernel
12 | {
13 | int rows;
14 | int cols;
15 | float data[];
16 | };
17 |
18 | void main()
19 | {
20 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0).xy;
21 | float dx = tex_offset.x;
22 | float dy = tex_offset.y;
23 |
24 | frag_color = vec4(0);
25 | for (int i = 0; i < rows; i++)
26 | {
27 | float t = tex_coord.t + (i - 0.5*(rows-1))*dy;
28 | for (int j = 0; j < cols; j++)
29 | {
30 | float s = tex_coord.s + (j - 0.5*(cols-1))*dx;
31 | vec4 current_value = max(textureCubeFace(screen_image, vec2(s, t), gl_Layer), 0.0);
32 | if (channels == 1)
33 | {
34 | current_value.gb = current_value.rr;
35 | current_value.a = 1;
36 | }
37 | frag_color += data[i*cols + j] * current_value;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/lut.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _LUT_GLSL_
2 | #define _LUT_GLSL_
3 |
4 | uniform sampler2D LUT;
5 | uniform float contribute;
6 |
7 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
8 | {
9 | ivec2 LUT_size = textureSize(LUT, 0);
10 | int block_width = 0;
11 | ivec2 block_shape = ivec2(0);
12 | if (LUT_size.x == LUT_size.y)
13 | {
14 | block_width = int(pow(LUT_size.x, 2.0/3.0));
15 | }
16 | else
17 | {
18 | block_width = min(LUT_size.x, LUT_size.y);
19 | }
20 | block_shape = ivec2(block_width);
21 |
22 | ivec2 block_size = LUT_size / block_shape;
23 | vec2 block_ratio = vec2(block_shape) / vec2(LUT_size);
24 | int n_blocks = block_size.x * block_size.y;
25 |
26 | vec4 color = clamp(textureLod(screen_image, tex_coord, 0), 0.0, 1.0);
27 | vec2 dxy = color.rg * (block_ratio - 1.0/LUT_size) + 0.5/LUT_size;
28 |
29 | float i_blockf = color.b * (n_blocks - 1);
30 | int i_block = int(i_blockf);
31 | float rear = i_blockf - i_block;
32 |
33 | ivec2 block_index = ivec2(i_block % block_size.x, i_block / block_size.x);
34 | vec2 start_xy = block_index * block_ratio;
35 | vec2 new_tex_coord = start_xy + dxy;
36 | vec4 new_color = textureLod(LUT, vec2(new_tex_coord.x, 1-new_tex_coord.y), 0);
37 |
38 | if (i_block < n_blocks-1)
39 | {
40 | block_index = ivec2((i_block+1) % block_size.x, (i_block+1) / block_size.x);
41 | start_xy = block_index * block_ratio;
42 | new_tex_coord = start_xy + dxy;
43 | new_color = mix(new_color, textureLod(LUT, vec2(new_tex_coord.x, 1-new_tex_coord.y), 0), rear);
44 | }
45 |
46 | return mix(color, new_color, contribute);
47 | }
48 |
49 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/median_gray_blur5.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _MEDIAN_GRAY_BLUR5_GLSL_
2 | #define _MEDIAN_GRAY_BLUR5_GLSL_
3 |
4 | #define KERNEL_WIDTH 5
5 |
6 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
7 | {
8 | float values[KERNEL_WIDTH*KERNEL_WIDTH];
9 | vec2 tex_offset = 1.0 / textureSize(screen_image, 0);
10 | float dx = tex_offset.x;
11 | float dy = tex_offset.y;
12 |
13 | int current_index = 0;
14 | float half_width = (KERNEL_WIDTH - 1.0)/2.0;
15 | for (float i = -half_width; i <= half_width; i += 1)
16 | {
17 | float y = tex_coord.y + dy*i;
18 | for (float j = -half_width; j <= half_width; j += 1)
19 | {
20 | float x = tex_coord.x + dx*j;
21 | values[current_index] = textureLod(screen_image, vec2(x, y), 0).r;
22 | current_index++;
23 | }
24 | }
25 |
26 | int N = KERNEL_WIDTH * KERNEL_WIDTH;
27 | for (int j = N-1; j >= 0; j--)
28 | {
29 | for (int i = 0; i < j; i++)
30 | {
31 | if (values[i] > values[i+1])
32 | {
33 | float temp = values[i];
34 | values[i] = values[i+1];
35 | values[i+1] = temp;
36 | }
37 | }
38 | }
39 |
40 | int half_index = (KERNEL_WIDTH - 1) / 2;
41 | if (KERNEL_WIDTH % 2 == 0)
42 | {
43 | return vec4(vec3(0.5*(values[half_index] + values[half_index+1])), 1);
44 | }
45 | else
46 | {
47 | return vec4(vec3(values[half_index]), 1);
48 | }
49 | }
50 |
51 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/mul_filter.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _MUL_FILTER_GLSL_
2 | #define _MUL_FILTER_GLSL_
3 |
4 | uniform sampler2D filter_image;
5 | uniform int filter_channels;
6 |
7 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
8 | {
9 | vec4 color0 = max(textureLod(screen_image, tex_coord, 0), 0.0);
10 | vec4 color1 = max(textureLod(filter_image, tex_coord, 0), 0.0);
11 | if (filter_channels == 1)
12 | {
13 | color1.gb = color1.rr;
14 | color1.a = 1;
15 | }
16 |
17 | return color0 * color1;
18 | }
19 |
20 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/slit_stretch.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _SLIT_STRETCH_GLSL_
2 | #define _SLIT_STRETCH_GLSL_
3 |
4 | float triWave(float x)
5 | {
6 | return(abs(mod(x-10.0, 20.0)-10.0)+1.0);
7 | }
8 |
9 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
10 | {
11 | vec2 uv = 2.0*(tex_coord-0.5);
12 |
13 | vec2 uvR = uv*(1.0-length(uv)/(triWave(iTime*5.0)));
14 | vec2 uvG = uv*(1.0-length(uv)/(triWave(iTime*5.0+0.1)));
15 | vec2 uvB = uv*(1.0-length(uv)/(triWave(iTime*5.0+0.2)));
16 |
17 | uvR = uvR/2.0 + 0.5;
18 | uvG = uvG/2.0 + 0.5;
19 | uvB = uvB/2.0 + 0.5;
20 |
21 | float R = max(texture(screen_image, uvR).r, 0.0);
22 | float G = max(texture(screen_image, uvG).g, 0.0);
23 | float B = max(texture(screen_image, uvB).b, 0.0);
24 |
25 | return vec4(R, G, B, 1.0);
26 | }
27 |
28 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/star_field.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _STAR_FIELD_GLSL_
2 | #define _STAR_FIELD_GLSL_
3 |
4 | #define M_PI acos(-1)
5 |
6 | #define H(P) fract(sin(dot(P,vec2(127.1,311.7)))*43758.545)
7 | #define pR(a) mat2(cos(a),sin(a),-sin(a),cos(a))
8 |
9 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
10 | {
11 | float t = iTime * 0.6;
12 | vec4 frag_color = max(texture(screen_image, tex_coord), 0.0);
13 |
14 | vec2 uv = (tex_coord-0.5) * 3.0;
15 |
16 | vec3 vuv = vec3(sin(iTime * 0.3), 1.0, cos(iTime));
17 | vec3 ro = vec3(0.0, 0.0, 134.0);
18 | vec3 vrp = vec3(5.0, sin(iTime) * 60.0, 20.0);
19 |
20 | vrp.xz * pR(iTime);
21 | vrp.yz * pR(iTime * 0.2);
22 |
23 | vec3 vpn = normalize(vrp - ro);
24 | vec3 u = normalize(cross(vuv, vpn));
25 | vec3 rd = normalize(vpn + uv.x * u + uv.y * cross(vpn, u));
26 |
27 | vec3 sceneColor = vec3(0.0, 0.0, 0.3);
28 | vec3 flareCol = vec3(0.0);
29 | float flareIntensivity = 0.0;
30 |
31 | for (float k = 0.0; k < 400.0; k++) {
32 | float r = H(vec2(k)) * 2.0 - 1.0;
33 | vec3 flarePos = vec3(H(vec2(k) * r) * 20.0 - 10.0, r * 8.0, (mod(sin(k / 200.0 * M_PI * 4.0) * 15.0 - t * 13.0 * k * 0.007, 25.0)));
34 | float v = max(abs(dot(normalize(flarePos), rd)), 0.0);
35 |
36 | flareIntensivity += pow(v, 30000.0) * 4.0;
37 | flareIntensivity += pow(v, 1e2) * 0.15;
38 | flareIntensivity *= 1.0 - flarePos.z / 25.0;
39 | flareCol += vec3(flareIntensivity) * (vec3(sin(r * 3.12 - k), r, cos(k) * 2.0)) * 0.3;
40 | }
41 |
42 | sceneColor += abs(flareCol);
43 | sceneColor = mix(sceneColor, sceneColor.rrr * 1.4, length(uv) / 2.0);
44 |
45 | frag_color += vec4(pow(sceneColor, vec3(1.1)), 1.0);
46 |
47 | return frag_color;
48 | }
49 |
50 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/PostProcessEffects/water_wave.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _WATER_WAVE_GLSL_
2 | #define _WATER_WAVE_GLSL_
3 |
4 | vec4 post_process(sampler2D screen_image, vec2 tex_coord)
5 | {
6 | vec2 uv = tex_coord * 0.8 + 0.1;
7 | uv += cos(iTime*vec2(6.0, 7.0) + uv*10.0)*0.02;
8 |
9 | return max(texture(screen_image, uv), 0.0);
10 | }
11 |
12 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/CookTorrance.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _COOKTORRANCE_GLSL_
2 | #define _COOKTORRANCE_GLSL_
3 |
4 | #include "../include/Material.glsl"
5 |
6 | float NormalDistributionFunction(vec3 halfway_vec, vec3 normal, float roughness)
7 | {
8 | roughness = mix(0.02, 1.0, roughness);
9 | float roughness4 = pow(roughness, 4);
10 | return roughness4 / pow(1 - (1 - roughness4)*pow(dot(normal, halfway_vec), 2), 2);
11 | }
12 |
13 | float GeometryFunction(float cos_to_light, float cos_to_camera, float roughness)
14 | {
15 | float k = pow(roughness + 1, 2) / 8;
16 | float G = cos_to_light/(cos_to_light*(1 - k) + k) * cos_to_camera/(cos_to_camera*(1 - k) + k);
17 | return G;
18 | }
19 |
20 | vec3 FresnelEquation(float cos_to_camera, vec3 base_color, float metallic)
21 | {
22 | vec3 F0 = mix(vec3(0.04), base_color, metallic);
23 | vec3 F = F0 + (1 - F0) * pow(1 - cos_to_camera, 5);
24 | return F;
25 | }
26 |
27 | vec3 CookTorrance_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
28 | {
29 | float cos_to_light = max(dot(normal, to_light), 0);
30 | float cos_to_camera = max(dot(normal, to_camera), 0);
31 | vec3 halfway_vec = normalize(to_light + to_camera);
32 | float D = NormalDistributionFunction(halfway_vec, normal, material.roughness);
33 | float G = GeometryFunction(cos_to_light, cos_to_camera, material.roughness);
34 | vec3 F = FresnelEquation(cos_to_camera, material.base_color, material.metallic);
35 | vec3 kd = (1 - F)*(1 - material.metallic);
36 | vec3 Lo = kd * material.base_color * cos_to_light + D*G*F / (4*cos_to_camera + 0.001);
37 | return material.shadow_visibility * Lo;
38 | }
39 |
40 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Flat.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _FLAT_GLSL_
2 | #define _FLAT_GLSL_
3 |
4 | #include "../include/Material.glsl"
5 |
6 | vec3 Flat_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
7 | {
8 | vec3 diffuse_color = material.base_color * Lambert_diffuse(to_light, normal);
9 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
10 | return material.shadow_visibility*diffuse_color + rim_color;
11 | }
12 |
13 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Fresnel.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _FRESNEL_GLSL_
2 | #define _FRESNEL_GLSL_
3 |
4 | #include "../include/Material.glsl"
5 |
6 | float Fresnel_diffuse(vec3 to_camera, vec3 normal, float rim_power)
7 | {
8 | float cos_to_camera = max(0, dot(to_camera, normal));
9 | return pow(1 - cos_to_camera, 1/(0.001 + rim_power));
10 | }
11 |
12 | vec3 Fresnel_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
13 | {
14 | return material.base_color * Fresnel_diffuse(to_camera, normal, material.rim_power);
15 | }
16 |
17 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Gouraud.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _GOURAUD_GLSL_
2 | #define _GOURAUD_GLSL_
3 |
4 | #include "Phong.glsl"
5 |
6 | vec3 Gouraud_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
7 | {
8 | return Phong_lighting(to_light, to_camera, normal, material);
9 | }
10 |
11 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Lambert.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _LAMBERT_GLSL_
2 | #define _LAMBERT_GLSL_
3 |
4 | #include "rim.glsl"
5 | #include "../include/Material.glsl"
6 |
7 | float Lambert_diffuse(vec3 to_light, vec3 normal)
8 | {
9 | return max(dot(to_light, normal), 0.0);
10 | }
11 |
12 | vec3 Lambert_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
13 | {
14 | vec3 diffuse_color = material.base_color * Lambert_diffuse(to_light, normal);
15 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
16 | return material.shadow_visibility * diffuse_color + rim_color;
17 | }
18 |
19 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Minnaert.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _MINNAERT_GLSL_
2 | #define _MINNAERT_GLSL_
3 |
4 | #include "rim.glsl"
5 | #include "../include/Material.glsl"
6 |
7 | float Minnaert_diffuse(vec3 to_light, vec3 to_camera, vec3 normal, float roughness)
8 | {
9 | float cos_to_light = dot(to_light, normal);
10 | float cos_to_camera = dot(to_camera, normal);
11 | return max(cos_to_light * pow(cos_to_light*cos_to_camera, roughness), 0.0);
12 | }
13 |
14 | vec3 Minnaert_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
15 | {
16 | vec3 diffuse_color = material.base_color * Minnaert_diffuse(to_light, to_camera, normal, material.roughness);
17 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
18 | return material.shadow_visibility * diffuse_color + rim_color;
19 | }
20 |
21 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/OrenNayar.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _ORENNAYAR_GLSL_
2 | #define _ORENNAYAR_GLSL_
3 |
4 | #include "rim.glsl"
5 | #include "../include/Material.glsl"
6 |
7 | vec3 OrenNayar_diffuse(vec3 to_light, vec3 to_camera, vec3 normal, float roughness, vec3 diffuse_color)
8 | {
9 | float cos_theta_i = dot(normal, to_light);
10 | float cos_theta_r = dot(normal, to_camera);
11 | float theta_i = acos(cos_theta_i);
12 | float theta_r = acos(cos_theta_r);
13 | float cos_phi_r_phi_i = dot(normalize(to_camera - cos_theta_r*normal), normalize(to_light - cos_theta_i*normal));
14 | float alpha = max(theta_r, theta_i);
15 | float beta = min(theta_r, theta_i);
16 | float sigma = 0.5*acos(-1)*roughness;
17 | float sigma2 = sigma*sigma;
18 | float C1 = 1 - 0.5 * sigma2 / (sigma2 + 0.33);
19 | float C2 = 0.45 * sigma2 / (sigma2 + 0.09);
20 | C2 *= (cos_phi_r_phi_i >= 0 ? sin(alpha) : sin(alpha) - pow(2*beta/M_PI, 3));
21 | float C3 = 2 * sigma2/(sigma2 + 0.09) * pow((alpha/M_PI)*(beta/M_PI), 2);
22 | float L1 = C1 + cos_phi_r_phi_i*C2*tan(beta) + (1 - abs(cos_phi_r_phi_i))*C3*tan(0.5*(alpha+beta));
23 | vec3 L2 = 0.17 * diffuse_color * sigma2 / (sigma2 + 0.13) * (1 - cos_phi_r_phi_i*pow(2*beta/M_PI, 2));
24 | return (L1 + L2) * max(cos_theta_i, 0.0);
25 | }
26 |
27 | vec3 OrenNayar_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
28 | {
29 | vec3 diffuse_color = material.base_color * OrenNayar_diffuse(to_light, to_camera, normal, material.roughness, material.base_color);
30 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
31 | return material.shadow_visibility * diffuse_color + rim_color;
32 | }
33 |
34 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Phong.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _PHONG_GLSL_
2 | #define _PHONG_GLSL_
3 |
4 | float Phong_specular(vec3 to_light, vec3 to_camera, vec3 normal, float shininess)
5 | {
6 | vec3 reflect_dir = reflect(-to_light, normal);
7 | float cos_out = max(dot(reflect_dir, to_camera), 0.0);
8 | return pow(cos_out, shininess);
9 | }
10 |
11 | vec3 Phong_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
12 | {
13 | vec3 diffuse_color = material.base_color * Lambert_diffuse(to_light, normal);
14 | vec3 specular_color = material.specular * Phong_specular(to_light, to_camera, normal, material.shininess);
15 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
16 | return material.shadow_visibility*(diffuse_color + specular_color) + rim_color;
17 | }
18 |
19 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/PhongBlinn.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _PHONGBLINN_GLSL_
2 | #define _PHONGBLINN_GLSL_
3 |
4 | float PhongBlinn_specular(vec3 to_light, vec3 to_camera, vec3 normal, float shininess)
5 | {
6 | vec3 halfway_vec = normalize(to_light + to_camera);
7 | float cos_out = max(dot(halfway_vec, normal), 0.0);
8 | return pow(cos_out, shininess);
9 | }
10 |
11 | vec3 PhongBlinn_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
12 | {
13 | vec3 diffuse_color = material.base_color * Lambert_diffuse(to_light, normal);
14 | vec3 specular_color = material.specular * PhongBlinn_specular(to_light, to_camera, normal, material.shininess);
15 | vec3 rim_color = material.base_color * rim(to_light, to_camera, normal, material.light_rim_power, material.rim_power);
16 | return material.shadow_visibility*(diffuse_color + specular_color) + rim_color;
17 | }
18 |
19 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/Toon.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _TOON_GLSL_
2 | #define _TOON_GLSL_
3 |
4 | #include "Phong.glsl"
5 |
6 | float Toonify(float value, uint bands, float softness)
7 | {
8 | return (soft_floor(value*(bands - 1) - softness/2, softness/2) + 1) / (bands - 1);
9 | }
10 |
11 | vec3 Toon_lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
12 | {
13 | float diffuse_factor = Lambert_diffuse(to_light, normal);
14 | vec3 diffuse_color = material.base_color * Toonify(diffuse_factor, material.diffuse_bands, material.diffuse_softness);
15 | float specular_factor = Phong_specular(to_light, to_camera, normal, material.shininess);
16 | vec3 specular_color = material.specular * Toonify(specular_factor, material.specular_bands, material.specular_softness);
17 | float rim_factor = pow(1 - dot(normal, to_camera), 1/(0.001+material.rim_power)) * pow(max(0, dot(to_light, normal)), 1/(1+material.light_rim_power));
18 | vec3 rim_color = material.base_color * soft_step(rim_factor-0.2, 0.05);
19 | return material.shadow_visibility*(diffuse_color + specular_color) + rim_color;
20 | }
21 |
22 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/lighting.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _LIGHTING_GLSL_
2 | #define _LIGHTING_GLSL_
3 |
4 | #include "Lambert.glsl"
5 |
6 | #if USE_SHADING_MODEL_FLAT
7 | #include "Flat.glsl"
8 | #endif
9 |
10 | #if USE_SHADING_MODEL_GOURAUD
11 | #include "Gouraud.glsl"
12 | #endif
13 |
14 | #if USE_SHADING_MODEL_PHONG
15 | #include "Phong.glsl"
16 | #endif
17 |
18 | #if USE_SHADING_MODEL_PHONG_BLINN
19 | #include "PhongBlinn.glsl"
20 | #endif
21 |
22 | #if USE_SHADING_MODEL_TOON
23 | #include "Toon.glsl"
24 | #endif
25 |
26 | #if USE_SHADING_MODEL_OREN_NAYAR
27 | #include "OrenNayar.glsl"
28 | #endif
29 |
30 | #if USE_SHADING_MODEL_MINNAERT
31 | #include "Minnaert.glsl"
32 | #endif
33 |
34 | #if USE_SHADING_MODEL_COOK_TORRANCE
35 | #include "CookTorrance.glsl"
36 | #endif
37 |
38 | #if USE_SHADING_MODEL_FRESNEL
39 | #include "Fresnel.glsl"
40 | #endif
41 |
42 | vec3 lighting(vec3 to_light, vec3 to_camera, vec3 normal, InternalMaterial material)
43 | {
44 | switch (material.shading_model)
45 | {
46 | #if USE_SHADING_MODEL_FLAT
47 | case SHADING_MODEL_FLAT: return Flat_lighting(to_light, to_camera, normal, material);
48 | #endif
49 | #if USE_SHADING_MODEL_GOURAUD
50 | case SHADING_MODEL_GOURAUD: return Gouraud_lighting(to_light, to_camera, normal, material);
51 | #endif
52 | #if USE_SHADING_MODEL_PHONG
53 | case SHADING_MODEL_PHONG: return Phong_lighting(to_light, to_camera, normal, material);
54 | #endif
55 | #if USE_SHADING_MODEL_PHONG_BLINN
56 | case SHADING_MODEL_PHONG_BLINN: return PhongBlinn_lighting(to_light, to_camera, normal, material);
57 | #endif
58 | #if USE_SHADING_MODEL_TOON
59 | case SHADING_MODEL_TOON: return Toon_lighting(to_light, to_camera, normal, material);
60 | #endif
61 | #if USE_SHADING_MODEL_OREN_NAYAR
62 | case SHADING_MODEL_OREN_NAYAR: return OrenNayar_lighting(to_light, to_camera, normal, material);
63 | #endif
64 | #if USE_SHADING_MODEL_MINNAERT
65 | case SHADING_MODEL_MINNAERT: return Minnaert_lighting(to_light, to_camera, normal, material);
66 | #endif
67 | #if USE_SHADING_MODEL_COOK_TORRANCE
68 | case SHADING_MODEL_COOK_TORRANCE:
69 | case SHADING_MODEL_PBR: return CookTorrance_lighting(to_light, to_camera, normal, material);
70 | #endif
71 | #if USE_SHADING_MODEL_FRESNEL
72 | case SHADING_MODEL_FRESNEL: return Fresnel_lighting(to_light, to_camera, normal, material);
73 | #endif
74 | default: return vec3(0);
75 | }
76 | }
77 |
78 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/ShadingModels/rim.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _RIM_GLSL_
2 | #define _RIM_GLSL_
3 |
4 | float rim(vec3 to_light, vec3 to_camera, vec3 normal, float light_rim_power, float material_rim_power)
5 | {
6 | if (light_rim_power < 1E-6 || material_rim_power < 1E-6)
7 | return 0;
8 | float light_rim = pow(clamp(0.5 - 0.5*dot(to_light, to_camera), 0, 1), 1/(0.001+light_rim_power));
9 | float material_rim = pow(clamp(1 - dot(normal, to_camera), 0, 1), 1/(0.001+material_rim_power));
10 | return light_rim * material_rim;
11 | }
12 |
13 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/FresnelRefract.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _FRESNELREFRACT_GLSL_
2 | #define _FRESNELREFRACT_GLSL_
3 |
4 | float fresnel_reflect_ratio(float n1, float n2, float cos_theta_i)
5 | {
6 | float sin_theta_i2 = 1 - cos_theta_i*cos_theta_i;
7 | float sin_theta_o2 = (n1*n1/(n2*n2))*sin_theta_i2;
8 | if (sin_theta_o2 >= 1)
9 | {
10 | return 1;
11 | }
12 |
13 | float cos_theta_o = sqrt(1 - sin_theta_o2);
14 | float n1_cos_theta_i = n1 * cos_theta_i;
15 | float n2_cos_theta_o = n2 * cos_theta_o;
16 | float n1_cos_theta_o = n1 * cos_theta_o;
17 | float n2_cos_theta_i = n2 * cos_theta_i;
18 | float Rs = (n1_cos_theta_i - n2_cos_theta_o) / (n1_cos_theta_i + n2_cos_theta_o);
19 | float Rp = (n1_cos_theta_o - n2_cos_theta_i) / (n1_cos_theta_o + n2_cos_theta_i);
20 |
21 | return clamp(0.5*(Rs*Rs + Rp*Rp), 0, 1);
22 | }
23 |
24 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/OIT.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _OIT_GLSL_
2 | #define _OIT_GLSL_
3 |
4 | #include "limits.glsl"
5 |
6 | float blend_weight1(float abs_z)
7 | {
8 | return clamp(10/(1E-5 + pow(abs_z/5, 2) + pow(abs_z/200, 6)), 1E-2, 3E3);
9 | }
10 |
11 | float blend_weight2(float abs_z)
12 | {
13 | return clamp(10/(1E-5 + pow(abs_z/5, 3) + pow(abs_z/200, 6)), 1E-2, 3E3);
14 | }
15 |
16 | float blend_weight3(float abs_z)
17 | {
18 | return clamp(10/(1E-5 + pow(abs_z/200, 4)), 1E-2, 3E3);
19 | }
20 |
21 | float blend_weight4(float dz)
22 | {
23 | return max(1E-2, 3E3*pow(1 - dz, 3));
24 | }
25 |
26 | void get_OIT_info(vec4 out_color, float abs_z, out vec4 accum, out float reveal)
27 | {
28 | float weight = out_color.a * blend_weight2(abs_z);
29 | accum = vec4(out_color.rgb*out_color.a, out_color.a) * weight;
30 | reveal = log(1 - out_color.a);
31 | }
32 |
33 | vec4 blend_composite(vec4 accum, float reveal)
34 | {
35 | if (hasinf(accum.rgb))
36 | {
37 | accum.rgb = vec3(accum.a);
38 | }
39 | vec3 average_color = accum.rgb / max(accum.a, 1E-6);
40 | return vec4(average_color, exp(reveal));
41 | }
42 |
43 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/ShadingInfo.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _SHADINGINFO_GLSL_
2 | #define _SHADINGINFO_GLSL_
3 |
4 | #include "Material.glsl"
5 | #include "background.glsl"
6 |
7 | struct ShadingInfo
8 | {
9 | vec4 color;
10 | #if USE_DYNAMIC_ENV_MAPPING
11 | uvec2 env_map_handle;
12 | #endif
13 | bool is_opaque_pass;
14 | bool is_sphere;
15 | mat3 world_TBN;
16 | vec3 world_pos;
17 | vec2 tex_coord;
18 | mat4 affine_transform;
19 | vec3 mesh_center;
20 | };
21 |
22 | struct PostShadingInfo
23 | {
24 | InternalMaterial material;
25 | #if USE_DYNAMIC_ENV_MAPPING
26 | uvec2 env_map_handle;
27 | #endif
28 | bool is_sphere;
29 | vec3 world_pos;
30 | vec3 world_normal;
31 | vec3 env_center;
32 | };
33 |
34 |
35 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/background.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _BACKGROUND_GLSL_
2 | #define _BACKGROUND_GLSL_
3 |
4 | struct Background
5 | {
6 | samplerCube skybox_map;
7 | sampler2D skydome_map;
8 | vec4 color;
9 | float distance;
10 | };
11 |
12 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/fog.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _FOG_GLSL_
2 | #define _FOG_GLSL_
3 |
4 | #include "math.glsl"
5 |
6 | #if USE_FOG
7 |
8 | #define FOG_MODE_LINEAR 9729
9 | #define FOG_MODE_EXP 2048
10 | #define FOG_MODE_EXP2 2049
11 |
12 | struct Fog
13 | {
14 | uint mode;
15 | vec3 color;
16 | float extinction_density;
17 | float inscattering_density;
18 | };
19 |
20 | vec3 fog_apply(Fog fog, vec3 color, float distance)
21 | {
22 | if (fog.extinction_density < 1E-6 && fog.inscattering_density < 1E-6)
23 | return color;
24 |
25 | float extinction = 1;
26 | float inscattering = 1;
27 | if (fog.mode == FOG_MODE_LINEAR)
28 | {
29 | extinction = max(0, 1 - fog.extinction_density*distance);
30 | inscattering = max(0, 1 - fog.inscattering_density*distance);
31 | }
32 | else if (fog.mode == FOG_MODE_EXP)
33 | {
34 | extinction = exp(-fog.extinction_density*distance);
35 | inscattering = exp(-fog.inscattering_density*distance);
36 | }
37 | else if (fog.mode == FOG_MODE_EXP2)
38 | {
39 | float d2 = distance*distance;
40 | extinction = exp(-fog.extinction_density*d2);
41 | inscattering = exp(-fog.inscattering_density*d2);
42 | }
43 | return color*extinction + fog.color * (1 - inscattering);
44 | }
45 |
46 | #endif
47 |
48 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/image_read_write.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _IMAGE_READ_WRITE_GLSL_
2 | #define _IMAGE_READ_WRITE_GLSL_
3 |
4 | #define imageRead(value_center, image, tex_coord) \
5 | vec4 value_center;\
6 | {\
7 | ivec2 image_size = imageSize(image);\
8 | float x_max = float(image_size.x - 1);\
9 | float y_max = float(image_size.y - 1);\
10 | \
11 | vec2 texel_coord = tex_coord * (vec2(image_size) - 1.0);\
12 | float x = floor(texel_coord.x);\
13 | float y = floor(texel_coord.y);\
14 | float x_rear = texel_coord.x - x;\
15 | float y_rear = texel_coord.y - y;\
16 | vec4 value1 = imageLoad(image, ivec2(x, y));\
17 | vec4 value2 = imageLoad(image, ivec2(min(x+1, x_max), y));\
18 | vec4 value3 = imageLoad(image, ivec2(x, min(y+1, y_max)));\
19 | vec4 value4 = imageLoad(image, ivec2(min(x+1, x_max), min(y+1, y_max)));\
20 | vec4 value12 = mix(value1, value2, x_rear);\
21 | vec4 value34 = mix(value3, value4, x_rear);\
22 | value_center = mix(value12, value34, y_rear);\
23 | }
24 |
25 | #define imageWrite(image, tex_coord, value) \
26 | {\
27 | ivec2 image_size = imageSize(image);\
28 | float x_max = float(image_size.x - 1);\
29 | float y_max = float(image_size.y - 1);\
30 | \
31 | vec2 texel_coord = tex_coord * (vec2(image_size) - 1.0);\
32 | float x = floor(texel_coord.x);\
33 | float y = floor(texel_coord.y);\
34 | float x_rear = texel_coord.x - x;\
35 | float y_rear = texel_coord.y - y;\
36 | \
37 | vec4 value1 = (1-x_rear)*(1-y_rear)*value;\
38 | vec4 value2 = x_rear*(1-y_rear)*value;\
39 | vec4 value3 = (1-x_rear)*y_rear*value;\
40 | vec4 value4 = x_rear*y_rear*value;\
41 | \
42 | ivec2 texel_coord1 = ivec2(x, y);\
43 | ivec2 texel_coord2 = ivec2(min(x+1, x_max), y);\
44 | ivec2 texel_coord3 = ivec2(x, min(y+1, y_max));\
45 | ivec2 texel_coord4 = ivec2(min(x+1, x_max), min(y+1, y_max));\
46 | \
47 | vec4 old_value1 = imageLoad(image, texel_coord1);\
48 | vec4 old_value2 = imageLoad(image, texel_coord2);\
49 | vec4 old_value3 = imageLoad(image, texel_coord3);\
50 | vec4 old_value4 = imageLoad(image, texel_coord4);\
51 | \
52 | imageStore(image, texel_coord1, old_value1+value1);\
53 | memoryBarrierImage();\
54 | \
55 | imageStore(image, texel_coord2, old_value2+value2);\
56 | memoryBarrierImage();\
57 | \
58 | imageStore(image, texel_coord3, old_value3+value3);\
59 | memoryBarrierImage();\
60 | \
61 | imageStore(image, texel_coord4, old_value4+value4);\
62 | memoryBarrierImage();\
63 | }
64 |
65 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/math.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _MATH_GLSL_
2 | #define _MATH_GLSL_
3 |
4 | const float M_PI = acos(-1);
5 | const float cos45 = 0.5*sqrt(2);
6 | const float sin45 = cos45;
7 |
8 | uint get_digit(uint value, uint p)
9 | {
10 | value /= p;
11 | return (value - value / 10 * 10);
12 | }
13 |
14 | float luminance(vec3 color)
15 | {
16 | return dot(color, vec3(0.2126, 0.7152, 0.0722));
17 | }
18 |
19 | float luminance(vec4 color)
20 | {
21 | return dot(color.rgb*color.a, vec3(0.2126, 0.7152, 0.0722));
22 | }
23 |
24 | bool is_equal(float a, float b)
25 | {
26 | return abs(a - b) <= (abs(a) < abs(b) ? abs(b) : abs(a)) * 1E-6;
27 | }
28 |
29 | float max3(vec3 v)
30 | {
31 | return max(max(v.x, v.y), v.z);
32 | }
33 |
34 | float max4(vec4 v)
35 | {
36 | return max(max(max(v.x, v.y), v.z), v.w);
37 | }
38 |
39 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/quat.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _QUAT_GLSL_
2 | #define _QUAT_GLSL_
3 |
4 | struct quat
5 | {
6 | float w;
7 | float x;
8 | float y;
9 | float z;
10 | };
11 |
12 | quat vec3_to_quat(vec3 v)
13 | {
14 | quat q;
15 | q.w = 0;
16 | q.x = v.x;
17 | q.y = v.y;
18 | q.z = v.z;
19 | return q;
20 | }
21 |
22 | quat vec4_to_quat(vec4 v)
23 | {
24 | quat q;
25 | q.w = v[0];
26 | q.x = v[1];
27 | q.y = v[2];
28 | q.z = v[3];
29 | return q;
30 | }
31 |
32 | quat quat_conj(quat q)
33 | {
34 | quat p;
35 | p.w = q.w;
36 | p.x = -q.x;
37 | p.y = -q.y;
38 | p.z = -q.z;
39 | return p;
40 | }
41 |
42 | quat quat_mult(quat p, quat q)
43 | {
44 | quat pq;
45 | pq.w = p.w*q.w - p.x*q.x - p.y*q.y - p.z*q.z;
46 | pq.x = p.w*q.x + p.x*q.w + p.y*q.z - p.z*q.y;
47 | pq.y = p.w*q.y - p.x*q.z + p.y*q.w + p.z*q.x;
48 | pq.z = p.w*q.z + p.x*q.y - p.y*q.x + p.z*q.w;
49 | return pq;
50 | }
51 |
52 | float quat_norm(quat q)
53 | {
54 | return sqrt(q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
55 | }
56 |
57 | quat quat_normalize(quat q)
58 | {
59 | quat result;
60 | float norm = quat_norm(q);
61 | result.w = q.w / norm;
62 | result.x = q.x / norm;
63 | result.y = q.y / norm;
64 | result.z = q.z / norm;
65 | return result;
66 | }
67 |
68 | vec3 quat_apply(quat q, vec3 v)
69 | {
70 | quat result = quat_mult(quat_mult(q, vec3_to_quat(v)), quat_conj(q));
71 | return vec3(result.x, result.y, result.z);
72 | }
73 |
74 | mat3 quat_to_mat3(quat q)
75 | {
76 | return mat3(1.0-2.0*(q.y*q.y + q.z*q.z), 2.0*(q.x*q.y + q.w*q.z), 2.0*(q.x*q.z - q.w*q.y),
77 | 2.0*(q.x*q.y - q.w*q.z), 1.0-2.0*(q.x*q.x + q.z*q.z), 2.0*(q.y*q.z + q.w*q.x),
78 | 2.0*(q.x*q.z + q.w*q.y), 2.0*(q.y*q.z - q.w*q.x), 1.0-2.0*(q.x*q.x + q.y*q.y));
79 | }
80 |
81 | mat4 quat_to_mat4(quat q)
82 | {
83 | return mat4(1.0-2.0*(q.y*q.y + q.z*q.z), 2.0*(q.x*q.y + q.w*q.z), 2.0*(q.x*q.z - q.w*q.y), 0.0,
84 | 2.0*(q.x*q.y - q.w*q.z), 1.0-2.0*(q.x*q.x + q.z*q.z), 2.0*(q.y*q.z + q.w*q.x), 0.0,
85 | 2.0*(q.x*q.z + q.w*q.y), 2.0*(q.y*q.z - q.w*q.x), 1.0-2.0*(q.x*q.x + q.y*q.y), 0.0,
86 | 0.0, 0.0, 0.0, 1.0);
87 | }
88 |
89 | #endif
--------------------------------------------------------------------------------
/glass_engine/glsl/include/tex_coord.glsl:
--------------------------------------------------------------------------------
1 | #ifndef _TEX_COORD_GLSL_
2 | #define _TEX_COORD_GLSL_
3 |
4 | #include "Material.glsl"
5 | #include "math.glsl"
6 |
7 | void transform_tex_coord(Material material, Material back_material, vec3 tex_coord, out vec3 new_tex_coord, out vec3 back_tex_coord)
8 | {
9 | new_tex_coord = tex_coord;
10 | new_tex_coord.st -= material.st_pivot;
11 | new_tex_coord.st *= material.st_scale;
12 | float st_angle_rad = material.st_rotation / 180.0 * M_PI;
13 | new_tex_coord.st = mat2(
14 | cos(st_angle_rad), sin(st_angle_rad),
15 | -sin(st_angle_rad), cos(st_angle_rad)
16 | ) * new_tex_coord.st;
17 | new_tex_coord.st += material.st_pivot;
18 | new_tex_coord.st += material.st_offset;
19 |
20 | back_tex_coord = tex_coord;
21 | back_tex_coord.st -= back_material.st_pivot;
22 | back_tex_coord.st *= back_material.st_scale;
23 | st_angle_rad = back_material.st_rotation / 180.0 * M_PI;
24 | back_tex_coord.st = mat2(
25 | cos(st_angle_rad), sin(st_angle_rad),
26 | -sin(st_angle_rad), cos(st_angle_rad)
27 | ) * back_tex_coord.st;
28 | back_tex_coord.st += back_material.st_pivot;
29 | back_tex_coord.st += back_material.st_offset;
30 | }
31 |
32 | #endif
--------------------------------------------------------------------------------
/glass_engine/images/glass_engine_logo256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/glass_engine/images/glass_engine_logo256.png
--------------------------------------------------------------------------------
/glass_engine/images/glass_engine_logo411.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/glass_engine/images/glass_engine_logo411.png
--------------------------------------------------------------------------------
/glass_engine/images/glass_engine_logo64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/glass_engine/images/glass_engine_logo64.png
--------------------------------------------------------------------------------
/glass_engine/images/start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Time-Coder/Glass-Engine/6c415fefc770882599a014e394e87fd1b8ea3b98/glass_engine/images/start.png
--------------------------------------------------------------------------------
/linux_install_python.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # sudo aptitude install libreadline-dev libbz2-dev liblzma-dev libsqlite3-dev tk-dev libffi-dev libgdbm-dev uuid-dev
6 |
7 | python_versions=("3.7.17" "3.8.20" "3.9.22" "3.10.17" "3.11.12" "3.12.10" "3.13.3")
8 | for version in ${python_versions[@]};
9 | do
10 | # wget --no-check-certificate https://npm.taobao.org/mirrors/python/$version/Python-$version.tar.xz -P ~/.pyenv/cache/
11 | pyenv install -v $version
12 | # pyenv local $version
13 | # $(pyenv which python) -m pip install pip --upgrade -i https://mirrors.aliyun.com/pypi/simple
14 | # $(pyenv which python) -m pip install -r requirements.txt --upgrade -i https://mirrors.aliyun.com/pypi/simple
15 | done;
16 |
--------------------------------------------------------------------------------
/mac_install_python.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # brew install xz
6 |
7 | python_versions=("3.7.9" "3.8.10" "3.9.13" "3.10.11" "3.11.7" "3.12.1")
8 | for version in ${python_versions[@]};
9 | do
10 | # wget --no-check-certificate https://npm.taobao.org/mirrors/python/$version/Python-$version.tar.xz -P ~/.pyenv/cache/
11 | # pyenv install $version
12 | pyenv local $version
13 | $(pyenv which python) -m pip install pip --upgrade -i https://mirrors.aliyun.com/pypi/simple
14 | $(pyenv which python) -m pip install -r requirements.txt --upgrade -i https://mirrors.aliyun.com/pypi/simple
15 | done;
16 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | PyOpenGL
2 | tree-sitter
3 | PyGLM
4 | numpy
5 | opencv-python
6 | wget
7 | requests
8 | chardet
9 | freetype-py
10 | pytweening
11 | setuptools
12 | wheel
13 | auditwheel
14 | twine
15 | pyinstaller
16 | pyflakes
17 | pycodestyle
18 | black
19 |
--------------------------------------------------------------------------------
/setup_glass.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 | import os
3 |
4 | def find_files(module, directory):
5 | file_list = []
6 | for root, _, files in os.walk(directory):
7 | for file in files:
8 | file_path = os.path.join(root, file)[(len(module) + 1) :]
9 | abs_file_path = os.path.abspath(os.path.join(root, file)).replace("\\", "/")
10 | if not os.path.isfile(abs_file_path):
11 | continue
12 |
13 | if "__glcache__" not in file_path:
14 | file_list.append(file_path.replace("\\", "/"))
15 | return file_list
16 |
17 | extra_files = ["LICENSE", "pcpp/LICENSE"]
18 | extra_files += find_files("glass", "glass/glsl")
19 | extra_files += find_files("glass", "glass/CodeCompressor/tree-sitter-glsl")
20 |
21 | with open("glass/README_PYPI.md", "r", encoding='utf-8') as in_file:
22 | long_description = in_file.read()
23 |
24 | setuptools.setup(
25 | name="python_glass",
26 | version="0.1.64",
27 | author="王炳辉 (BingHui-WANG)",
28 | author_email="binghui.wang@foxmail.com",
29 | description="OpenGL wrapper for Glass-Engine",
30 | long_description=long_description,
31 | long_description_content_type="text/markdown",
32 | url="https://github.com/Time-Coder/Glass-Engine",
33 | packages=setuptools.find_packages(exclude=['*glass_engine*', '*assimpy*']),
34 | package_data={
35 | 'glass': extra_files
36 | },
37 | include_package_data=False,
38 | python_requires=">=3.7",
39 | install_requires=[
40 | "PyOpenGL",
41 | "PyGLM",
42 | "numpy",
43 | "opencv-python",
44 | "wget",
45 | "requests",
46 | "chardet",
47 | "tree-sitter>=0.20.4",
48 | "tree-sitter-glsl37",
49 | "typeguard",
50 | "typing_extensions"
51 | ],
52 | classifiers=[
53 | "Programming Language :: Python :: 3",
54 | "License :: OSI Approved :: MIT License",
55 | 'Operating System :: OS Independent',
56 | ],
57 | entry_points={'pyinstaller40': ['hook-dirs = glass.__pyinstaller:get_hook_dirs']}
58 | )
59 |
--------------------------------------------------------------------------------
/setup_glass_engine.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 | import os
3 |
4 | def find_files(module, directory):
5 | file_list = []
6 | for root, _, files in os.walk(directory):
7 | for file in files:
8 | file_path = os.path.join(root, file)[(len(module) + 1) :]
9 | abs_file_path = os.path.abspath(os.path.join(root, file)).replace("\\", "/")
10 | if not os.path.isfile(abs_file_path):
11 | continue
12 |
13 | if "__glcache__" not in file_path:
14 | file_list.append(file_path.replace("\\", "/"))
15 | return file_list
16 |
17 | with open("glass_engine/README_PYPI.md", "r", encoding='utf-8') as fh:
18 | long_description = fh.read()
19 |
20 | extra_files = ["images/glass_engine_logo64.png", "LICENSE"]
21 | extra_files += find_files("glass_engine", "glass_engine/glsl")
22 |
23 | setuptools.setup(
24 | name="glass_engine",
25 | version="0.1.64",
26 | author="王炳辉 (BingHui-WANG)",
27 | author_email="binghui.wang@foxmail.com",
28 | description="An easy-to-use 3D rendering engine for Python",
29 | long_description=long_description,
30 | long_description_content_type="text/markdown",
31 | url="https://github.com/Time-Coder/Glass-Engine",
32 | packages=setuptools.find_packages(include=['glass_engine*']),
33 | package_data={
34 | 'glass_engine': extra_files,
35 | },
36 | include_package_data=False,
37 | python_requires=">=3.7",
38 | install_requires=[
39 | "python-glass==0.1.64",
40 | "assimpy>=5.4.3.3",
41 | "pytweening"
42 | ],
43 | classifiers=[
44 | "Programming Language :: Python :: 3",
45 | "License :: OSI Approved :: MIT License",
46 | 'Operating System :: OS Independent',
47 | ],
48 | entry_points={'pyinstaller40': ['hook-dirs = glass_engine.__pyinstaller:get_hook_dirs']}
49 | )
50 |
--------------------------------------------------------------------------------
/static_check.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 |
4 |
5 | def check_syntax(folder_name):
6 | subprocess.call([sys.executable, "-m", "pyflakes", folder_name])
7 |
8 |
9 | def check_style(folder_name):
10 | subprocess.call([sys.executable, "-m", "pycodestyle", folder_name])
11 |
12 |
13 | check_syntax("glass")
14 | check_syntax("glass_engine")
15 |
16 | # check_style("glass")
17 | # check_style("glass_engine")
18 |
--------------------------------------------------------------------------------
/to-do-list.txt:
--------------------------------------------------------------------------------
1 | * Material 纹理随物体缩放
2 | * 灯的颜色不对
3 | * 不需要 geometry shader 的不使用 geometry shader
4 | * Lights 优先采用 Uniform Buffer Object,超过 32 个再使用 Shader Storage Buffer Object
5 | * uniform, uniform block, buffer 采用 tree-sitter 解析,删除原来的正则解析
6 | * uniform, uniform block, buffer 结构体绑定变量,变量属性改变透传 uniform, uniform block, buffer 结构体属性改变
7 | * 优化增量更新
8 | * 兼容 glfw, tikinter, pygame
9 |
10 | * 完善全部类型注解
--------------------------------------------------------------------------------
/upload_assimpy.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 |
4 | subprocess.call([sys.executable, "-m", "twine", "upload", "dist/assimpy-*.tar.gz", "dist/assimpy-*.whl", "--verbose"])
--------------------------------------------------------------------------------
/upload_glass.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 |
4 | subprocess.call([sys.executable, "-m", "twine", "upload", "dist/python_glass-*.tar.gz", "dist/python_glass-*.whl", "--verbose"])
5 |
--------------------------------------------------------------------------------
/upload_glass_engine.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import sys
3 |
4 | subprocess.call([sys.executable, "-m", "twine", "upload", "dist/glass_engine-*.tar.gz", "dist/glass_engine-*.whl", "--verbose"])
5 |
--------------------------------------------------------------------------------
/windows_install_python.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | set python_versions=3.7.9 3.7.9-win32 3.8.10 3.8.10-win32 3.9.13 3.9.13-win32 3.10.11 3.10.11-win32 3.11.7 3.11.7-win32 3.12.1 3.12.1-win32
4 |
5 | for %%v in (%python_versions%) do (
6 | pyenv install %%v
7 | pyenv local %%v
8 | python -m pip install pip --upgrade -i https://mirrors.aliyun.com/pypi/simple
9 | @REM python -m pip install -r requirements.txt --upgrade -i https://mirrors.aliyun.com/pypi/simple
10 | )
11 |
--------------------------------------------------------------------------------