Пример #1
0
    def __init__(self, filename: str, scale: vec3 = vec3(1.0)):
        super().__init__()
        self._filename = filename
        self._wavefront_vertices: glm.array
        self.scale = vec3(scale)

        self.vertices: glm.array
        self.normals: glm.array
        self.indices: glm.array

        self._store = Store()

        self.obj = pywavefront.Wavefront(self._store.find_path(filename))
        for _, material in self.obj.materials.items():
            v = material.vertices
            v = [v[i:i + 8] for i in range(0, len(v), 8)]

            self.vertices = glm.array([vec3(chunk[5:8]) * scale for chunk in v])
            self.normals = glm.array([vec3(chunk[2:5]) for chunk in v])
            self.indices = glm.array([u32vec3(i*3, i*3+1, i*3+2) for i in range(len(self.vertices) // 3)])

            # only use first mesh
            break

        # create bbox
        self._bbox = BoundingBox(vec3(inf), vec3(-inf))
        for v in self.vertices:
            self._bbox.vec3_extend(v)
Пример #2
0
    def update_device_vaos(self) -> None:
        """Update VAO when device list changes."""
        self._num_devices = len(self.core.devices)

        if self._num_devices > 0:
            scale = glm.scale(mat4(), vec3(3, 3, 3))
            mats = glm.array([mat * scale for mat in self._devices])
            cols = glm.array([
                self.colors[i % len(self.colors)]
                for i in range(self._num_devices)
            ])
            ids = glm.array(ctypes.c_int, *list(range(self._num_devices)))

            self._bind_vao_mat_col_id(self._vaos['camera'], mats, cols, ids)
Пример #3
0
 def __init__(self, data_type, array_type=GL_ARRAY_BUFFER, max_size=10000):
     self._data_type = data_type
     self._array_type = array_type
     self._arr = glm.array(data_type()) * max_size
     self._index = 0
     self._vbo = glGenBuffers(1)
     self._changed = True
def main():
    # initializing glfw library
    if not glfw.init():
        raise Exception("glfw can not be initialized!")

    # Configure the OpenGL context.
    # If we are planning to use anything above 2.1 we must at least
    # request a 3.3 core context to make this work across platforms.
    if "Windows" in pltf.platform():
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
    else:
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)

    # 4 MSAA is a good default with wide support
    glfw.window_hint(glfw.SAMPLES, 4)

    # creating the window
    window = glfw.create_window(1280, 720, "My OpenGL window", None, None)

    # check if window was created
    if not window:
        glfw.terminate()
        raise Exception("glfw window can not be created!")

    # Query the actual framebuffer size so we can set the right viewport later
    # -> glViewport(0, 0, framebuffer_size[0], framebuffer_size[1])
    framebuffer_size = glfw.get_framebuffer_size(window)

    # set window's position
    glfw.set_window_pos(window, 100, 100)

    # make the context current
    glfw.make_context_current(window)

    # glClearColor(0.5, 0.5, 0.5, 1.0)
    print("GL_RENDERER   = ", glGetString(GL_RENDERER).decode("utf8"))
    print("GL_VERSION    = ", glGetString(GL_VERSION).decode("utf8"))

    # the main application loop
    while not glfw.window_should_close(window):
        glfw.poll_events()
        # glClear(GL_COLOR_BUFFER_BIT)
        COLOR = glm.array(
            glm.vec4([
                glm.sin(glfw.get_time()) * 0.5 + 0.5,
                glm.cos(glfw.get_time()) * 0.5 + 0.5, 0.0, 1.0
            ]))
        glClearBufferfv(GL_COLOR, 0, COLOR.ptr)

        glfw.swap_buffers(window)

    # terminate glfw, free up allocated resources
    glfw.terminate()
Пример #5
0
def get_cylinder_vertices(
        cylinder: CylinderObject3D,
        sides: int) -> Tuple[glm.array, glm.array, glm.array]:
    """Get vertices, normals, and indices for a cylinder object.

    Args:
        cylinder: A CylinderObject3D.
        sides: An int representing the number of sides per circle.
    """
    # faster way to calculate points along a circle
    theta = 2.0 * math.pi / sides
    tan_factor = tan(theta)
    rad_factor = cos(theta)

    x = vec3(cylinder.radius, 0.0, 0.0)

    vertices = []
    for i in range(sides):
        vertices.append(vec3(0.0, 0.0, 0.0) + x)
        vertices.append(vec3(0.0, 0.0, cylinder.height) + x)
        delta = vec3(x[1] * tan_factor, -x[0] * tan_factor, 0.0)
        x = (x + delta) * rad_factor
    vertices.append(vec3(0.0, 0.0, 0.0))
    vertices.append(vec3(0.0, 0.0, cylinder.height))

    normals = []
    for i in range(len(vertices)):
        n = vec3(vertices[i].x, vertices[i].y, 0.0) * mat3(
            cylinder.trans_matrix)
        normals.append(glm.normalize(n))
        vertices[i] = vec3(vec4(vertices[i], 1.0) * cylinder.trans_matrix)
    normals[-2] = vec3(0.0, 0.0, -1.0) * mat3(cylinder.trans_matrix)
    normals[-1] = vec3(0.0, 0.0, 1.0) * mat3(cylinder.trans_matrix)

    indices = []
    for i in range(0, sides * 2, 2):
        i2 = (i + 2) % (2 * sides)
        i3 = (i + 3) % (2 * sides)
        indices.extend((u32vec3(i, i + 1, i2), u32vec3(i + 1, i3, i2),
                        u32vec3(2 * sides, i,
                                i2), u32vec3(2 * sides + 1, i3, i + 1)))

    return glm.array(vertices), glm.array(normals), glm.array(indices)
Пример #6
0
    def create_vaos(self) -> None:
        """Bind VAOs to define vertex data."""
        vbo = glGenBuffers(1)

        # initialize camera box
        # TODO: update to obj file
        vertices = glm.array(
            vec3(-1.0, -0.5, -1.0),  # bottom
            vec3(-1.0, -0.5, 1.0),
            vec3(-1.0, 0.5, 1.0),
            vec3(-1.0, 0.5, -1.0),
            vec3(1.0, -0.5, -1.0),  # right
            vec3(-1.0, -0.5, -1.0),
            vec3(-1.0, 0.5, -1.0),
            vec3(1.0, 0.5, -1.0),
            vec3(1.0, -0.5, 1.0),  # top
            vec3(1.0, -0.5, -1.0),
            vec3(1.0, 0.5, -1.0),
            vec3(1.0, 0.5, 1.0),
            vec3(-1.0, -0.5, 1.0),  # left
            vec3(1.0, -0.5, 1.0),
            vec3(1.0, 0.5, 1.0),
            vec3(-1.0, 0.5, 1.0),
            vec3(1.0, 0.5, -1.0),  # back
            vec3(-1.0, 0.5, -1.0),
            vec3(-1.0, 0.5, 1.0),
            vec3(1.0, 0.5, 1.0),
            vec3(-1.0, -0.5, -1.0),  # front
            vec3(1.0, -0.5, -1.0),
            vec3(1.0, -0.5, 1.0),
            vec3(-1.0, -0.5, 1.0),
        )
        glBindBuffer(GL_ARRAY_BUFFER, vbo)
        glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr,
                     GL_STATIC_DRAW)

        self._vaos['box'] = glGenVertexArrays(1)
        glBindVertexArray(self._vaos['box'])
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)

        self._vaos['camera'] = glGenVertexArrays(1)
        glBindVertexArray(self._vaos['camera'])
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)
Пример #7
0
    def __init__(self, start: vec3, end: vec3, radius: float):
        super().__init__()
        self.start: vec3 = vec3(start)
        self.end: vec3 = vec3(end)
        self.radius: float = radius

        self.height: float = glm.distance(self.start, self.end)
        self.normal: vec3 = glm.normalize(self.end - self.start)

        self.b1: vec3
        self.b2: vec3
        self.b1, self.b2 = orthonormal_basis_of(self.normal)

        # calculate rotation matrix for cylinder
        self.trans_matrix: mat4 = glm.orientation(vec3(0.0, 0.0, 1.0), self.normal)

        # add translation to matrix
        self.trans_matrix[0][3] = start.x
        self.trans_matrix[1][3] = start.y
        self.trans_matrix[2][3] = start.z

        # get corners of OBB
        points = glm.array(
            vec3(self.radius, self.radius, 0.0),
            vec3(-self.radius, self.radius, 0.0),
            vec3(self.radius, -self.radius, 0.0),
            vec3(-self.radius, -self.radius, 0.0),
            vec3(self.radius, self.radius, self.height),
            vec3(-self.radius, self.radius, self.height),
            vec3(self.radius, -self.radius, self.height),
            vec3(-self.radius, -self.radius, self.height))

        # inflate OBB into AABB
        # TODO:
        #     BoundingBox _should_ have default values - we shouldn't have to
        #     initialize with inf and -inf manually. but if we do that,
        #     it seems to initialize with other BoundingBox's values.
        #     Something weird is going on with (I presume) glm pointers?
        self._bbox = BoundingBox(vec3(inf), vec3(-inf))
        for v in points:
            self._bbox.vec3_extend(vec3(vec4(v, 1.0) * self.trans_matrix))
Пример #8
0
    def update_action_vaos(self) -> None:
        """Update VAOs when action list changes."""
        self._vaos['line'].clear()
        self._vaos['point'].clear()

        # --- bind data for lines ---

        for key, value in self._items['line'].items():
            # ignore if 1 or fewer points
            if len(value) <= 1:
                continue

            points = glm.array([vec3(mat[1][3]) for mat in value])

            vbo = glGenBuffers(1)
            glBindBuffer(GL_ARRAY_BUFFER, vbo)
            glBufferData(GL_ARRAY_BUFFER, points.nbytes, points.ptr,
                         GL_STATIC_DRAW)

            vao = glGenVertexArrays(1)
            glBindVertexArray(vao)
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,
                                  ctypes.c_void_p(0))
            glEnableVertexAttribArray(0)
            self._vaos['line'][key] = vao

            glBindVertexArray(0)

        # --- bind data for points ---

        point_mats: glm.array = None
        point_cols: glm.array = None
        point_ids: glm.array = None
        scale = glm.scale(mat4(), vec3(3, 3, 3))

        for key, value in self._items['point'].items():
            new_mats = glm.array([p[1] * scale for p in value])
            color = shade_color(vec4(self.colors[key % len(self.colors)]),
                                -0.3)
            new_cols = glm.array([color] * len(value))

            # if point is selected, darken its color
            for i, v in enumerate(value):
                # un-offset ids
                if (v[0] - self._num_devices) in self.core.selected_points:
                    new_cols[i] = shade_color(vec4(new_cols[i]), 0.6)

            new_ids = glm.array.from_numbers(ctypes.c_int,
                                             *(p[0] for p in value))

            point_mats = new_mats if point_mats is None else point_mats.concat(
                new_mats)
            point_cols = new_cols if point_cols is None else point_cols.concat(
                new_cols)
            point_ids = new_ids if point_ids is None else point_ids.concat(
                new_ids)

        # we're done if no points to set
        if not self._items['point']:
            return

        self._num_points = sum(len(i) for i in self._items['point'].values())

        self._bind_vao_mat_col_id(self._vaos['box'], point_mats, point_cols,
                                  point_ids)
Пример #9
0
def get_aabb_vertices(
        aabb: AABBObject3D) -> Tuple[glm.array, glm.array, glm.array]:
    """Get vertices, normals, and indices for an axis-aligned box object.

    Args:
        cylinder: An AABBObject3D.
    """
    vertices = glm.array(
        vec3(aabb.upper.x, aabb.lower.y, aabb.upper.z),  # front
        vec3(aabb.lower.x, aabb.lower.y, aabb.upper.z),
        vec3(aabb.lower.x, aabb.lower.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.lower.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.upper.y, aabb.upper.z),  # top
        vec3(aabb.lower.x, aabb.upper.y, aabb.upper.z),
        vec3(aabb.lower.x, aabb.lower.y, aabb.upper.z),
        vec3(aabb.upper.x, aabb.lower.y, aabb.upper.z),
        vec3(aabb.upper.x, aabb.upper.y, aabb.upper.z),  # right
        vec3(aabb.upper.x, aabb.lower.y, aabb.upper.z),
        vec3(aabb.upper.x, aabb.lower.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.lower.x, aabb.lower.y, aabb.lower.z),  # bottom
        vec3(aabb.lower.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.lower.y, aabb.lower.z),
        vec3(aabb.lower.x, aabb.lower.y, aabb.lower.z),  # left
        vec3(aabb.lower.x, aabb.lower.y, aabb.upper.z),
        vec3(aabb.lower.x, aabb.upper.y, aabb.upper.z),
        vec3(aabb.lower.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.upper.x, aabb.upper.y, aabb.upper.z),  # back
        vec3(aabb.upper.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.lower.x, aabb.upper.y, aabb.lower.z),
        vec3(aabb.lower.x, aabb.upper.y, aabb.upper.z),
    )
    normals = glm.array(
        vec3(0.0, -1.0, 0.0),  # front
        vec3(0.0, -1.0, 0.0),
        vec3(0.0, -1.0, 0.0),
        vec3(0.0, -1.0, 0.0),
        vec3(0.0, 0.0, 1.0),  # top
        vec3(0.0, 0.0, 1.0),
        vec3(0.0, 0.0, 1.0),
        vec3(0.0, 0.0, 1.0),
        vec3(1.0, 0.0, 0.0),  # right
        vec3(1.0, 0.0, 0.0),
        vec3(1.0, 0.0, 0.0),
        vec3(1.0, 0.0, 0.0),
        vec3(0.0, 0.0, -1.0),  # bottom
        vec3(0.0, 0.0, -1.0),
        vec3(0.0, 0.0, -1.0),
        vec3(0.0, 0.0, -1.0),
        vec3(-1.0, 0.0, 0.0),  # left
        vec3(-1.0, 0.0, 0.0),
        vec3(-1.0, 0.0, 0.0),
        vec3(-1.0, 0.0, 0.0),
        vec3(0.0, 1.0, 0.0),  # back
        vec3(0.0, 1.0, 0.0),
        vec3(0.0, 1.0, 0.0),
        vec3(0.0, 1.0, 0.0),
    )
    indices = glm.array(
        u32vec3(0, 1, 2),  # front
        u32vec3(2, 3, 0),
        u32vec3(4, 5, 6),  # top
        u32vec3(6, 7, 4),
        u32vec3(8, 9, 10),  # right
        u32vec3(10, 11, 8),
        u32vec3(12, 13, 14),  # bottom
        u32vec3(14, 15, 12),
        u32vec3(16, 17, 18),  # left
        u32vec3(18, 19, 16),
        u32vec3(20, 21, 22),  # back
        u32vec3(22, 23, 20),
    )

    return vertices, normals, indices
Пример #10
0
        for args in gen_args("#uM{C}{R}".format(C=C, R=R) + "V{R}".format(R=R)*C + "_" + "_".join(["M{C}{R}M{c}{r}".format(C=C, R=R, c=c, r=r) for c in range(2, 5) for r in range(2,5)]) + "__fFiI"):
            fassert(type(args[0]), args[1:])

## quat
for args in gen_args("#u-_V3_M33_M44_NV3_V3V3_NNNN_Q__f"): # need support for conversion constructors
    fassert(glm.quat, args)

## dquat
for args in gen_args("#u-_V3_M33_M44_NV3_V3V3_NNNN_Q__F"): # need support for conversion constructors
    fassert(glm.dquat, args)

## array
for args in gen_args("V_M_Q_VV_MM_QQ_VVV_MMM_QQQ"):
    fassert(glm.array, args)

assert glm.array([glm.vec4() for x in range(10)])
assert glm.array(tuple([glm.vec4() for x in range(10)]))
assert glm.array({x : glm.vec4() for x in range(10)}.values())
assert glm.array(memoryview(glm.array([glm.vec4() for x in range(10)])))

assert glm.array([glm.quat() for x in range(10)])
assert glm.array(tuple([glm.quat() for x in range(10)]))
assert glm.array({x : glm.quat() for x in range(10)}.values())
assert glm.array(memoryview(glm.array([glm.quat() for x in range(10)])))

assert glm.array([glm.mat4() for x in range(10)])
assert glm.array(tuple([glm.mat4() for x in range(10)]))
assert glm.array({x : glm.mat4() for x in range(10)}.values())
assert glm.array(memoryview(glm.array([glm.mat4() for x in range(10)])))

arr = glm.array(glm.mat4(), glm.mat4(2))
Пример #11
0
    def __init__(self, a = 1.0, b = 1.0, c = 1.0):
        # 编译着色器
        self.shaderProgram = compileProgram(
            compileShader(vertexShaderSource, GL_VERTEX_SHADER),
            compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER)
        )
        self.transformIndex = glGetUniformLocation(self.shaderProgram, "transform")
        # self.textureIndex = glGetUniformLocation(self.shaderProgram, "myTexture")
        # 链接顶点属性
        a2, b2, c2 = a / 2.0, b / 2.0, c / 2.0
        vertices = [
            -a2, -c2, -b2, 0.0, 0.0,
            a2, -c2, -b2, 1.0, 0.0,
             a2, c2, -b2, 1.0, 1.0,
             a2, c2, -b2, 1.0, 1.0,
             -a2, c2, -b2, 0.0, 1.0,
             -a2, -c2, -b2, 0.0, 0.0,
             
             -a2, -c2, b2, 0.0, 0.0,
             a2, -c2, b2, 1.0, 0.0,
             a2, c2, b2, 1.0, 1.0,
             a2, c2, b2, 1.0, 1.0,
             -a2, c2, b2, 0.0, 1.0,
             -a2, -c2, b2, 0.0, 0.0,

             -a2, c2, b2, 1.0, 0.0,
             -a2, c2, -b2, 1.0, 1.0,
             -a2, -c2, -b2, 0.0, 1.0,
             -a2, -c2, -b2, 0.0, 1.0,
             -a2, -c2, b2, 0.0, 0.0,
             -a2, c2, b2, 1.0, 0.0,

             a2, c2, b2, 1.0, 0.0,
             a2, c2, -b2, 1.0, 1.0,
             a2, -c2, -b2, 0.0, 1.0,
             a2, -c2, -b2, 0.0, 1.0,
             a2, -c2, b2, 0.0, 0.0,
             a2, c2, b2, 1.0, 0.0,

             -a2, -c2, -b2, 0.0, 1.0,
             a2, -c2, -b2, 1.0, 1.0,
             a2, -c2, b2, 1.0, 0.0,
             a2, -c2, b2, 1.0, 0.0,
             -a2, -c2, b2, 0.0, 0.0,
             -a2, -c2, -b2, 0.0, 1.0,

             -a2, c2, -b2, 0.0, 1.0,
             a2, c2,-b2, 1.0, 1.0,
             a2, c2, b2, 1.0, 0.0,
             a2, c2, b2, 1.0, 0.0,
             -a2, c2, b2, 0.0, 0.0,
             -a2, c2,-b2, 0.0, 1.0
        ]
        # vertexData = glm.array([glm.float32(vertex) for vertex in vertices])
        vertexData = glm.array(glm.float32, *vertices)
        vertexBuffer = glGenBuffers(1) # VBO 顶点缓冲数据
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer)
        glBufferData(GL_ARRAY_BUFFER, vertexData.nbytes, vertexData.ptr, GL_STATIC_DRAW) # 只有array有这个nbytes和ptr
        self.vertexArray = glGenVertexArrays(1) # VAO 顶点数组对象
        glBindVertexArray(self.vertexArray)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), ctypes.c_void_p(0)) # 最后一个参数必须强制转换为void*
        # https://github.com/mcfletch/pyopengl/issues/3
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), ctypes.c_void_p(3 * sizeof(GLfloat)))
        glEnableVertexAttribArray(1)
        glBindVertexArray(0) # 用完别忘解绑
        # 设置纹理贴图
        image = Image.open("box.png")
        width, height = image.size
        raw_image = image.tobytes("raw", "RGBA")
        self.texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) # 重复边缘
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # 临近插值
        # glPixelStorei(GL_UNPACK_ALIGNMENT, 1) # 默认4字节对齐, 可以改成1或者用RGBA
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, raw_image)
        # glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
        glBindTexture(GL_TEXTURE_2D, 0)
        # 初始化一下变换矩阵
        self.rorate(0, 0, 0)