1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
import platform
from pathlib import Path
import moderngl
import pytest
from headless import HeadlessTestCase
from moderngl_window import resources
from moderngl_window.exceptions import ImproperlyConfigured
from moderngl_window.meta import ProgramDescription
from moderngl_window.opengl.program import ReloadableProgram
resources.register_dir((Path(__file__).parent / 'fixtures' / 'resources').resolve())
class ProgramLoadersTestCase(HeadlessTestCase):
window_size = (16, 16)
aspect_ratio = 1.0
def test_single(self):
"""Load a single file glsl program"""
program = resources.programs.load(ProgramDescription(path='programs/white.glsl'))
self.assertIsInstance(program, moderngl.Program)
# Ensure attribute is present
program['in_position']
self.assertIsInstance(program.extra.get('meta'), ProgramDescription)
def test_single_feedback(self):
"""Load transform feedback shader"""
program = resources.programs.load(ProgramDescription(path='programs/feedback.glsl'))
self.assertIsInstance(program, moderngl.Program)
def test_single_geometry(self):
"""Load single glsl file with gemotry shader"""
program = resources.programs.load(ProgramDescription(path='programs/billboards/billboards.glsl'))
self.assertIsInstance(program, moderngl.Program)
def test_single_tesselation(self):
"""Load single glsl file with tessellation"""
program = resources.programs.load(ProgramDescription(path='programs/terrain/terrain.glsl'))
self.assertIsInstance(program, moderngl.Program)
def test_single_reloadable(self):
"""Load a single file glsl program as reloadable"""
program = resources.programs.load(ProgramDescription(path='programs/white.glsl', reloadable=True))
self.assertIsInstance(program, ReloadableProgram)
# Ensure attribute is present
program['in_position']
self.assertIsInstance(program.extra.get('meta'), ProgramDescription)
self.assertEqual(program.name, 'programs/white.glsl')
self.assertIsInstance(program.ctx, moderngl.Context)
self.assertIsNotNone(program.get('in_position', None))
self.assertIsNotNone(program.mglo)
self.assertGreater(program.glo, 0)
program.subroutines
program.geometry_input
program.geometry_output
program.geometry_vertices
program._members
repr(program)
def test_separate_geometry(self):
program = resources.programs.load(ProgramDescription(
vertex_shader="programs/billboards/billboards_vs.glsl",
geometry_shader="programs/billboards/billboards_gs.glsl",
fragment_shader="programs/billboards/billboards_fs.glsl",
))
self.assertIsInstance(program, moderngl.Program)
def test_separate_tesselation(self):
"""Load a more complex tesselation program from separate files"""
program = resources.programs.load(ProgramDescription(
vertex_shader="programs/terrain/terrain_vs.glsl",
tess_control_shader="programs/terrain/terrain_tc.glsl",
tess_evaluation_shader="programs/terrain/terrain_te.glsl",
fragment_shader="programs/terrain/terrain_fs.glsl",
))
self.assertIsInstance(program, moderngl.Program)
def test_separate_relodable(self):
"""Load a more complex tesselation program from separate files"""
program = resources.programs.load(ProgramDescription(
vertex_shader="programs/terrain/terrain_vs.glsl",
tess_control_shader="programs/terrain/terrain_tc.glsl",
tess_evaluation_shader="programs/terrain/terrain_te.glsl",
fragment_shader="programs/terrain/terrain_fs.glsl",
reloadable=True,
))
self.assertIsInstance(program, ReloadableProgram)
def test_single_not_found(self):
"""Ensure ImproperlyConfigured is raised when shaders are not found"""
with self.assertRaises(ImproperlyConfigured):
resources.programs.load(ProgramDescription(path='programs/nonexist.glsl'))
def test_separate_not_found(self):
"""Ensure ImproperlyConfigured is raised when shaders are not found"""
with self.assertRaises(ImproperlyConfigured):
resources.programs.load(ProgramDescription(
vertex_shader="programs/notfound_vs.glsl",
geometry_shader="programs/notfound_geo.glsl",
tess_control_shader="programs/notfound_tc.glsl",
tess_evaluation_shader="programs/notfound_te.glsl",
fragment_shader="programs/notfound_fs.glsl",
))
@pytest.mark.skipif(platform.system() == 'Darwin', reason="Compute shader not possible on OSX")
def test_compute_shader(self):
"""Attempt loading a compute shader"""
path = 'programs/compute.glsl'
descr = ProgramDescription(compute_shader=path)
self.assertEqual(descr.compute_shader, path)
program = resources.programs.load(descr)
self.assertIsInstance(program, moderngl.ComputeShader)
def test_include(self):
program = resources.programs.load(ProgramDescription(path='programs/include_test.glsl'))
self.assertIsInstance(program, moderngl.Program)
def test_varyings_override(self):
"""Specify varyings during program creation"""
path = 'programs/varyings.glsl'
descr = ProgramDescription(vertex_shader=path, varyings=["value_1", "value_2"])
program = resources.programs.load(descr)
|