Example #1
0
    def load_object(self, object, obj_idx=None, smooth=False, wireframe=False):
        vertex_data = None
        if isinstance(object, str):
            object = ShapeModel(fname=object)
        elif isinstance(object, Obj):
            vertex_data = object
            assert not smooth, 'not supported'

        if isinstance(object, ShapeModel):
            if smooth:
                verts, tex, norms, faces = object.export_smooth_faces()
            else:
                verts, tex, norms, faces = object.export_angular_faces()

            vertex_data = Obj(verts, tex, norms, faces)
            texture_data = object.load_texture()

        assert vertex_data is not None, 'wrong object type'

        if wireframe:
            w_vbo = self._ctx.buffer(vertex_data.pack('vx vy vz'))
            w_obj = self._ctx.simple_vertex_array(self._wireframe_prog, w_vbo, 'vertexPosition_modelFrame')
        else:
            texture = None
            if texture_data is not None:
                texture = self._ctx.texture(texture_data.T.shape, 1, np.flipud(texture_data).tobytes())
                texture.build_mipmaps()

            vbo = self._ctx.buffer(vertex_data.pack('vx vy vz nx ny nz tx ty'))
            obj = self._ctx.simple_vertex_array(self._prog, vbo, 'vertexPosition_modelFrame', 'vertexNormal_modelFrame', 'aTexCoords')

            s_vbo = self._ctx.buffer(vertex_data.pack('vx vy vz'))
            s_obj = self._ctx.simple_vertex_array(self._shadow_prog, s_vbo, 'vertexPosition_modelFrame')

        if obj_idx is None:
            if wireframe:
                self._w_objs.append(w_obj)
            else:
                self._objs.append(obj)
                self._s_objs.append(s_obj)
                self._raw_objs.append(vertex_data)
                self._textures.append(texture)
        else:
            if wireframe:
                self._w_objs[obj_idx] = w_obj
            else:
                self._objs[obj_idx] = obj
                self._s_objs[obj_idx] = s_obj
                self._raw_objs[obj_idx] = vertex_data
                self._textures[obj_idx] = texture

        return len(self._w_objs if wireframe else self._objs)-1
Example #2
0
    def load_meshes_and_textures(self, path):
        meshes = {}
        mesh_attributes = {}
        try:
            with open(os.path.join(path, "config.yaml"), "r") as config:
                try:
                    mesh_attributes = yaml.safe_load(config)
                except yaml.YAMLError as exc:
                    raise Exception(exc)
        except EnvironmentError as e:
            print("[!] Could not load mesh attributes file:\
                  {}".format(os.path.join(path, "config.yaml")))
            raise EnvironmentError(e)

        for file in os.listdir(path):
            if os.path.isfile(os.path.join(path, file)):
                if file.endswith('_frame.obj'):
                    file_name = os.path.split(file)[-1]
                    try:
                        obj_file = Obj.open(os.path.join(path, file_name))
                        contour_obj_front_file = Obj.open(
                            os.path.join(path,
                                         mesh_attributes[file_name]['contour_front']))
                        contour_obj_back_file = Obj.open(
                            os.path.join(path,
                                         mesh_attributes[file_name]['contour_back']))
                        contour_png = Image.open(
                            os.path.join(
                                path, mesh_attributes[file_name]['texture'])
                        ).transpose(Image.FLIP_LEFT_RIGHT).transpose(
                            Image.FLIP_TOP_BOTTOM).convert('RGB')
                        contour_texture = self.context.texture(
                            contour_png.size, 3, contour_png.tobytes())
                        contour_texture.build_mipmaps()
                    except Exception as e:
                        raise Exception(e)

                    meshes[file_name] = {
                        'center': Vector3(mesh_attributes[file_name]['center']),
                        'width': mesh_attributes[file_name]['width'],
                        'height': mesh_attributes[file_name]['height'],
                        'contour_obj_front': contour_obj_front_file,
                        'contour_obj_back': contour_obj_back_file,
                        'contour_texture': contour_texture,
                        'obj': obj_file
                    }

        if len(meshes.items()) is 0:
            raise Exception("Meshes not loaded!")

        return meshes
Example #3
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_vert, 1.0);
                    v_vert = in_vert;
                    v_norm = in_norm;
                    v_text = in_text;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
                }
            '''),
        ])

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']

        obj = Obj.open(local('data', 'crate.obj'))
        img = Image.open(local('data', 'crate.png')).transpose(
            Image.FLIP_TOP_BOTTOM).convert('RGB')
        self.texture = self.ctx.texture(img.size, 3, img.tobytes())
        self.texture.use()

        self.vbo = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
        self.vao = self.ctx.simple_vertex_array(
            self.prog, self.vbo, ['in_vert', 'in_norm', 'in_text'])
Example #4
0
    def load_obj(self, filename):
        if not os.path.isfile(filename):
            print('{} is not an existing regular file!'.format(filename))
            return

        obj = Obj.open(filename)

        # TODO: not very efficient, consider using an element index array later
        self.vao = self.ctx.simple_vertex_array(
            self.prog,
            self.ctx.buffer(obj.pack('vx vy vz tx ty')),
            ['in_vert', 'in_text']
        )
Example #5
0
import moderngl as ModernGL
from ModernGL.ext.obj import Obj
from PIL import Image
from pyrr import Matrix44

# Data files

vertex_data = Obj.open('data/sitting.obj').pack()
texture_image = Image.open('data/wood.jpg')
vertex_shader_source = open('data/shader.vert').read()
fragment_shader_source = open('data/shader.frag').read()

# Context creation

ctx = ModernGL.create_standalone_context()

# Shaders

prog = ctx.program(vertex_shader=vertex_shader_source,
                   fragment_shader=fragment_shader_source)

# Matrices and Uniforms

perspective = Matrix44.perspective_projection(45.0, 1.0, 0.1, 1000.0)
lookat = Matrix44.look_at(
    (-85, -180, 140),
    (0.0, 0.0, 65.0),
    (0.0, 0.0, 1.0),
)

mvp = perspective * lookat
Example #6
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_vert, 1.0);
                    v_vert = in_vert;
                    v_norm = in_norm;
                    v_text = in_text;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform vec3 Color;
                uniform bool UseTexture;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    if (UseTexture) {
                        f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
                    } else {
                        f_color = vec4(Color * lum, 1.0);
                    }
                }
            '''),
        ])

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']
        self.color = self.prog.uniforms['Color']
        self.use_texture = self.prog.uniforms['UseTexture']

        self.objects = {}

        for name in [
                'ground', 'grass', 'billboard', 'billboard-holder',
                'billboard-image'
        ]:
            obj = Obj.open(local('data', 'scene-1-%s.obj' % name))
            vbo = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
            vao = self.ctx.simple_vertex_array(
                self.prog, vbo, ['in_vert', 'in_norm', 'in_text'])
            self.objects[name] = vao

        img = Image.open(local('data', 'infographic-1.jpg')).transpose(
            Image.FLIP_TOP_BOTTOM).convert('RGB')
        self.texture1 = self.ctx.texture(img.size, 3, img.tobytes())
        self.texture1.build_mipmaps()

        self.texture2 = self.ctx.texture(self.wnd.size, 3)
        depth_attachment = self.ctx.depth_renderbuffer(self.wnd.size)
        self.fbo = self.ctx.framebuffer(self.texture2, depth_attachment)
    def initializeModernGL(self):
        """Initialize all things related to running modernGL
        """

        self.ctx = mgl.create_context()

        self.prog = self.ctx.program(
            vertex_shader='''
                #version 330
                
                uniform mat4 Mvp;
                
                // Per vertex
                in vec3 in_vert_c;
                //in vec3 in_norm_c;
                in vec2 in_text_c;
                
                in vec3 in_vert_s;
                //in vec3 in_norm_s;
                in vec2 in_text_s;
                
                // Per object
                in vec3 in_pos;
                in mat3 in_rotMat;
                in vec3 in_size;
                in float texindex;
                in int shape;
                
                out vec3 v_vert;
                flat out int out_texindex;
                //out vec3 v_norm;
                out vec2 v_text;
                
                vec3 in_vert;
                vec2 in_text;
                //vec3 in_norm;
                                
                void main() {
                    // if shape is 0, it's a cube; if it's 1, it's a sphere
                    if (shape==1) {
                        in_vert = in_vert_s;
                        v_text = in_text_s;
                        //in_norm = in_norm_s;
                        }
                    else {
                        in_vert = in_vert_c;
                        v_text = in_text_c;
                        //in_norm = in_norm_c;
                        }
                    v_vert = (in_vert * in_size) * in_rotMat + in_pos;
                    //v_norm = (in_norm * in_size) * in_rotMat + in_pos;
                    gl_Position = Mvp * vec4(v_vert, 1.0);
                    out_texindex = int(texindex);

                }
            ''',
            fragment_shader='''
                #version 330
                uniform sampler2D textures[2];
                //uniform vec3 Light;
                
                flat in int out_texindex;
                in vec3 v_vert;
                //in vec3 v_norm;
                in vec2 v_text;
                
                out vec4 f_color;
                
                void main() {
                    
                    //float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    //vec3 base = vec3(0.5, 0.5, 0.5) * lum;
                    //vec3 spec = vec3(1.0, 1.0, 1.0) * pow(lum, 6);
                    vec4 tex = texture(textures[out_texindex], v_text);
                    //f_color = vec4(base * 0.1 + tex.rgb * lum + spec, tex.a);
                    f_color = vec4(tex.rgb, tex.a);
                }
            ''',
        )

        # Assign self.mvp to the uniform Mvp in the modernGL program
        self.mvp = self.prog['Mvp']

        # This should be programmatically determined, but basically I'm telling
        # the program that I've loaded two textures which can be accessed with
        # either a 0 or a 1 in the fragment shader.
        self.prog['textures'].value = [0, 1]

        # Haven't totally figured out how to use this stuff yet
        #        self.light = self.prog.uniforms['Light']
        #        self.light.value = (0,0,0) #-140.0, -300.0, 350.0

        # Uses an .obj file for vertex, texture, and surface normal information
        self.cubeobj = Obj.open(objDirectory + '\\cube\\cube.obj')
        self.sphereobj = Obj.open(objDirectory + '\\sphere\\Sphere.obj')

        # Each of these buffers provides the vertex and texture position info
        # to the vertex shader. Note that I should really be using a separate
        # program for cubes and spheres, but I've found a way to make this
        # work for now.
        # Only one gets used when rendering each entity.
        cubeVertBuffer = self.ctx.buffer(self.cubeobj.pack('vx vy vz tx ty'))
        sphereVertBuffer = self.ctx.buffer(
            self.sphereobj.pack('vx vy vz tx ty'))

        # entityBuffer is set up to provide the position, orientation, size,
        # texture index (each texture is loaded in Level), and shape type
        # (cube or sphere).
        self.entityBuffer = self.ctx.buffer(reserve=1024 * 1024)

        # Connect all of the buffers to a vertex array object which will be in
        # charge of rendering.
        vao_content = [
            (cubeVertBuffer, '3f 2f', 'in_vert_c', 'in_text_c'),
            (sphereVertBuffer, '3f 2f', 'in_vert_s', 'in_text_s'),
            (self.entityBuffer, '3f 9f 3f 1f 1i/i', 'in_pos', 'in_rotMat',
             'in_size', 'texindex', 'shape'),
        ]

        self.vao = self.ctx.vertex_array(self.prog, vao_content)
Example #8
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;

                in vec3 in_color;
                in vec3 in_origin;
                in mat3 in_basis;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec3 v_color;

                void main() {
                    v_vert = in_origin + in_basis * in_vert;
                    v_norm = in_basis * in_norm;
                    v_color = in_color;
                    gl_Position = Mvp * vec4(v_vert, 1.0);
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec3 v_color;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    f_color = vec4(v_color * lum, 1.0);
                }
            '''),
        ])

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']

        obj = Obj.open(local('data', 'lowpoly_toy_car.obj'))

        self.vbo1 = self.ctx.buffer(obj.pack('vx vy vz nx ny nz'))
        self.vbo2 = self.ctx.buffer(
            struct.pack(
                '15f',
                1.0,
                1.0,
                1.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                1.0,
            ) * len(cars))
        self.vao = self.ctx.vertex_array(self.prog, [
            (self.vbo1, '3f3f', ['in_vert', 'in_norm']),
            (self.vbo2, '3f3f9f/i', ['in_color', 'in_origin', 'in_basis']),
        ])
Example #9
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_move;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_vert + in_move, 1.0);
                    v_vert = in_vert + in_move;
                    v_norm = in_norm;
                    v_text = in_text;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
                }
            '''),
        ])

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']

        obj = Obj.open(local('data', 'crate.obj'))
        img = Image.open(local('data', 'crate.png')).transpose(
            Image.FLIP_TOP_BOTTOM).convert('RGB')
        self.texture = self.ctx.texture(img.size, 3, img.tobytes())
        self.texture.build_mipmaps()
        self.texture.use()

        self.vbo1 = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
        self.vbo2 = self.ctx.buffer(reserve=12 * 1024)
        self.vao = self.ctx.vertex_array(self.prog, [
            (self.vbo1, '3f3f2f', ['in_vert', 'in_norm', 'in_text']),
            (self.vbo2, '3f/i', ['in_move']),
        ])

        self.crate_a = np.random.uniform(0.7, 0.8, 32 * 32)
        self.crate_b = np.random.uniform(0.0, 6.3, 32 * 32)
        self.crate_x = (np.tile(np.arange(32), 32) - 16) * 1.5
        self.crate_y = (np.repeat(np.arange(32), 32) - 16) * 1.5
        self.crate_x += np.random.uniform(-0.2, 0.2, 32 * 32)
        self.crate_y += np.random.uniform(-0.2, 0.2, 32 * 32)
Example #10
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.canvas_prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                in vec2 in_vert;
                out vec2 v_vert;

                void main() {
                    gl_Position = vec4(in_vert * 2.0 - 1.0, 0.0, 1.0);
                    v_vert = in_vert;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform sampler2D Texture;

                in vec2 v_vert;

                out vec4 f_color;

                void main() {
                    f_color = texture(Texture, v_vert);
                }
            '''),
        ])

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_vert, 1.0);
                    v_vert = in_vert;
                    v_norm = in_norm;
                    v_text = in_text;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    vec3 base = vec3(0.5, 0.5, 0.5) * lum;
                    vec3 spec = vec3(1.0, 1.0, 1.0) * pow(lum, 5.7);
                    vec4 tex = texture(Texture, v_text);
                    f_color = vec4(base * 0.1 + tex.rgb * lum + spec, tex.a);
                }
            '''),
        ])

        self.canvas_vbo = self.ctx.buffer(
            np.array([0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0],
                     dtype='f4').tobytes())
        self.canvas_vao = self.ctx.simple_vertex_array(self.canvas_prog,
                                                       self.canvas_vbo,
                                                       ['in_vert'])

        bg_img = Image.open(local('data', 'mug-background.jpg')).transpose(
            Image.FLIP_TOP_BOTTOM).convert('RGB')
        self.bg_texture = self.ctx.texture(bg_img.size, 3, bg_img.tobytes())

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']

        sticker_img = Image.open(local(
            'data', 'mug-pymet-logo.png')).transpose(
                Image.FLIP_TOP_BOTTOM).convert('RGBA')
        self.sticker_texture = self.ctx.texture(sticker_img.size, 4,
                                                sticker_img.tobytes())
        self.sticker_texture.build_mipmaps(0, 2)

        self.mug_texture = self.ctx.texture((1, 1), 3)
        self.mug_texture.write(struct.pack('3B', 10, 10, 10))

        obj = Obj.open(local('data', 'mug.obj'))
        self.mug_vbo = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
        self.mug_vao = self.ctx.simple_vertex_array(
            self.prog, self.mug_vbo, ['in_vert', 'in_norm', 'in_text'])

        segs = 32
        radius = 29.94
        bottom = 6.601
        top = 57.856
        left = -163.12 * np.pi / 180.0
        right = 11.25 * np.pi / 180.0

        lin = np.linspace(left, right, segs)
        sticker_vertices = np.array([
            np.repeat(np.cos(lin) * radius, 2),
            np.repeat(np.sin(lin) * radius, 2),
            np.tile([bottom, top], segs),
            np.repeat(np.cos(lin), 2),
            np.repeat(np.sin(lin), 2),
            np.tile([0.0, 0.0], segs),
            np.repeat(np.linspace(0.0, 1.0, segs), 2),
            np.tile([0.0, 1.0], segs),
        ])

        self.sticker_vbo = self.ctx.buffer(
            sticker_vertices.T.astype('f4').tobytes())
        self.sticker_vao = self.ctx.simple_vertex_array(
            self.prog, self.sticker_vbo, ['in_vert', 'in_norm', 'in_text'])
Example #11
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.obj = Obj.open(
            os.path.join(os.path.dirname(__file__), 'data',
                         'sitting_dummy.obj'))
        self.wood = Image.open(
            os.path.join(os.path.dirname(__file__), 'data', 'wood.jpg'))

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    v_vert = in_vert;
                    v_norm = in_norm;
                    v_text = in_text;
                    gl_Position = Mvp * vec4(v_vert, 1.0);
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform sampler2D Texture;
                uniform vec4 Color;
                uniform vec3 Light;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = dot(normalize(v_norm), normalize(v_vert - Light));
                    lum = acos(lum) / 3.14159265;
                    lum = clamp(lum, 0.0, 1.0);
                    lum = lum * lum;
                    lum = smoothstep(0.0, 1.0, lum);
                    lum *= smoothstep(0.0, 80.0, v_vert.z) * 0.3 + 0.7;
                    lum = lum * 0.8 + 0.2;

                    vec3 color = texture(Texture, v_text).rgb;
                    color = color * (1.0 - Color.a) + Color.rgb * Color.a;
                    f_color = vec4(color * lum, 1.0);
                }

            '''),
        ])

        self.light = self.prog.uniforms['Light']
        self.color = self.prog.uniforms['Color']
        self.mvp = self.prog.uniforms['Mvp']

        self.texture = self.ctx.texture(self.wood.size, 3, self.wood.tobytes())
        self.texture.build_mipmaps()

        self.vbo = self.ctx.buffer(self.obj.pack('vx vy vz nx ny nz tx ty'))
        self.vao = self.ctx.simple_vertex_array(
            self.prog, self.vbo, ['in_vert', 'in_norm', 'in_text'])
Example #12
0
    def __init__(self, wnd):
        self.wnd = wnd
        self.ctx = ModernGL.create_context()

        self.prog = self.ctx.program([
            self.ctx.vertex_shader('''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_vert;
                in vec3 in_norm;
                in vec2 in_text;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_vert, 1.0);
                    v_vert = in_vert;
                    v_norm = in_norm;
                    v_text = in_text;
                }
            '''),
            self.ctx.fragment_shader('''
                #version 330

                uniform vec3 Light;
                uniform vec3 Color;
                uniform bool UseTexture;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    if (UseTexture) {
                        f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
                    } else {
                        f_color = vec4(Color * lum, 1.0);
                    }
                }
            '''),
        ])

        self.mvp = self.prog.uniforms['Mvp']
        self.light = self.prog.uniforms['Light']
        self.color = self.prog.uniforms['Color']
        self.use_texture = self.prog.uniforms['UseTexture']

        self.objects = {}

        for name in [
                'ground', 'grass', 'billboard', 'billboard-holder',
                'billboard-image'
        ]:
            obj = Obj.open(local('data', 'scene-1-%s.obj' % name))
            vbo = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
            vao = self.ctx.simple_vertex_array(
                self.prog, vbo, ['in_vert', 'in_norm', 'in_text'])
            self.objects[name] = vao

        figure_size = (640, 360)

        temp = io.BytesIO()
        plt.figure(0, figsize=(figure_size[0] / 72, figure_size[1] / 72))

        mu, sigma = 100, 15
        x = mu + sigma * np.random.randn(10000)
        n, bins, patches = plt.hist(x, 50, normed=1, facecolor='r', alpha=0.75)

        plt.axis([40, 160, 0, 0.03])
        plt.grid(True)
        plt.show()

        plt.savefig(temp, format='raw', dpi=72)
        temp.seek(0)

        img = Image.frombytes('RGBA', figure_size, temp.read()).transpose(
            Image.FLIP_TOP_BOTTOM).convert('RGB')
        self.texture = self.ctx.texture(img.size, 3, img.tobytes())
        self.texture.build_mipmaps()
Example #13
0
def main():
    # Data files

    vertex_data = Obj.open('data/sitting.obj').pack()
    texture_image = Image.open('data/wood.jpg')
    vertex_shader_source = open('data/shader.vert').read()
    fragment_shader_source = open('data/shader.frag').read()

    # Context creation

    ctx = ModernGL.create_standalone_context()

    # Shaders

    prog = ctx.program(vertex_shader=vertex_shader_source,
                       fragment_shader=fragment_shader_source)

    # Matrices and Uniforms

    perspective = Matrix44.perspective_projection(45.0, 1.0, 0.1, 1000.0)
    lookat = Matrix44.look_at(
        (-85, -180, 140),
        (0.0, 0.0, 65.0),
        (0.0, 0.0, 1.0),
    )

    mvp = perspective * lookat

    prog['Light'].value = (-140.0, -300.0, 350.0)
    prog['Color'].value = (1.0, 1.0, 1.0, 0.25)
    prog['Mvp'].write(mvp.astype('f4').tobytes())

    # Texture

    texture = ctx.texture(texture_image.size, 3, texture_image.tobytes())
    texture.build_mipmaps()

    # Vertex Buffer and Vertex Array

    vbo = ctx.buffer(vertex_data)
    vao = ctx.simple_vertex_array(prog, vbo,
                                  *['in_vert', 'in_text', 'in_norm'])

    # Framebuffers

    fbo = ctx.framebuffer(
        ctx.renderbuffer((512, 512)),
        ctx.depth_renderbuffer((512, 512)),
    )

    # Rendering

    fbo.use()
    ctx.enable(ModernGL.DEPTH_TEST)
    ctx.clear(0.9, 0.9, 0.9)
    texture.use()
    vao.render()

    # Loading the image using Pillow

    data = fbo.read(components=3, alignment=1)
    img = Image.frombytes('RGB', fbo.size, data, 'raw', 'RGB', 0, -1)
    img.save('output.png')
Example #14
0
def load_data(ctx,
              data_path=None,
              vertex_path=None,
              fragment_path=None,
              object_path=None,
              texture_path=None):
    """Loads texture data, vertex and fragment shaders and object data.

    Args:
        ctx (ModernGL.context.Context): the OpenGL context
        vertex_path (str, optional): Path to vertex shader
        fragment_path (str, optional): Path to fragment shader
        object_path (str, optional): Path to model's vertex data
        texture_path (str, optional): Path to texture file

    Updates:
        background_color
        texture_image
        model_data
        program

        texture
        model
        color


    Returns:
        tuple: opengl program, texture, vertex_data
    """
    global foreground_color
    global background_color
    global texture_image
    global texture_data
    global model_data
    global program

    global texture
    global model
    global color

    data_path = data_path or _find_data_folder()

    # Build file lists
    files = os.listdir(data_path)
    colors = list(itertools.product(
        [0, 1], repeat=3))  # (0, 0, 0), (0, 0, 1), ... (1, 1, 1)
    models = [
        Obj.open(os.path.join(data_path, filename)).pack()
        for filename in files if filename.endswith('.obj')
    ]
    textures = [
        Image.open(os.path.join(data_path, filename)) for filename in files
        if filename.endswith('.jpg')
    ]
    textures = [t for t in textures if t.mode == 'RGB']

    # Setup global generators
    color = _eternal_generator(colors)
    texture = _eternal_generator(textures)
    model = _eternal_generator(models)

    # Setup keyboard control parameters
    background_color = next(color)
    foreground_color = next(color)
    texture_image = next(texture)
    model_data = next(model)

    texture_data = ctx.texture(texture_image.size, 3, texture_image.tobytes())
    texture_data.build_mipmaps()

    # Setup files
    vertex_path = vertex_path or f'{data_path}/glfw-simple-window.vert'
    fragment_path = fragment_path or f'{data_path}/glfw-simple-window.frag'
    object_path = object_path or f'{data_path}/mug.obj'

    program = _load_shaders(ctx, vertex_path, fragment_path)