예제 #1
0
    def take_screenshot(self, quick):
        """
        takes a screenshot of the OpenGLWidget. saves it in the screenshots folder with .
        :return:
        """
        GL.glReadBuffer(GL.GL_FRONT)
        pixels = GL.glReadPixels(0, 0, self.width(), self.height(), GL.GL_RGB,
                                 GL.GL_UNSIGNED_BYTE)
        i = Image.frombytes('RGB', (self.width(), self.height()), pixels,
                            'raw')

        # if quick, save at screenshots/date_screenshot.jpg
        # else ask for location

        if not os.path.exists("outputs/screenshots") or not os.path.isdir(
                "outputs/screenshots"):
            os.mkdir("outputs/screenshots")

        if quick:
            # if the screenshot folder exists save it, else print an error.
            if os.path.exists("outputs/screenshots") and os.path.isdir(
                    "outputs/screenshots"):
                now = datetime.datetime.now()
                filename = str(
                    "outputs/screenshots/%d-%d-%d_%d-%d-%d_screenshot.jpg" %
                    (now.year, now.month, now.day, now.hour, now.minute,
                     now.second))
                i.save(filename, "JPEG")

                # checks if the file exists. If not, some unknown error occured in the Image library.
                if not os.path.exists(filename) or not os.path.isfile(
                        filename):
                    raise VisualizationError(
                        "Screenshot couldn't be saved due to an unknown reason.",
                        Level.WARNING)
            else:
                raise VisualizationError(
                    "Couldn't create the screenshot folder.", Level.WARNING)

        else:
            directory = "."
            if os.path.exists("outputs/screenshots") and os.path.isdir(
                    "outputs/screenshots"):
                directory = "outputs/screenshots"

            path = TopQFileDialog(
                self.world.vis.get_main_window()).getSaveFileName(
                    options=(TopQFileDialog.Options()),
                    filter="*.jpg;;*.png;;*.bmp",
                    directory=directory)

            if path[0] == '':
                return

            if path[0].endswith(".jpg") or path[0].endswith(".jpeg") or \
                    path[0].endswith(".png") or path[0].endswith(".bmp"):
                i.save(path[0])
            else:
                i.save(path[0] + path[1].replace('*', ''))
예제 #2
0
    def __init__(self, vertex_file, fragment_file, model_file):
        """
        Superclass for Opengl Programs.
        compiles the given shader source files, gives access to the shared uniform variables of the shaders,
        loads the model mesh and calls the abstract init_buffer function with the loaded data
        :param vertex_file: file path to the vertex shader
        :param fragment_file: file path to the fragment shader
        :param model_file: file path to the .obj file
        """
        # creating GL Program
        self._program = GL.glCreateProgram()
        # loading shader source files
        self._vertex = GL.glCreateShader(GL.GL_VERTEX_SHADER)
        self._fragment = GL.glCreateShader(GL.GL_FRAGMENT_SHADER)
        self.amount = 0

        try:
            vert_source = open(vertex_file).read()
        except IOError as e:
            raise VisualizationError(
                "Vertex shader file couldn't be loaded:\n%s" % str(e),
                Level.CRITICAL)

        try:
            frag_source = open(fragment_file).read()
        except IOError as e:
            raise VisualizationError(
                "Fragment shader file couldn't be loaded:\n%s" % str(e),
                Level.CRITICAL)

        self.vbos = []
        self._init_shaders(vert_source, frag_source)

        GL.glUseProgram(self._program)

        self.light_angle = 0
        v, n, t = load_obj_file("components/models/" + model_file)
        self.size = len(v)

        self._vao = GL.glGenVertexArrays(1)
        self.use()
        self._init_buffers(v, n, t)
        GL.glBindVertexArray(0)

        self._init_uniforms()
예제 #3
0
    def _init_shaders(self, vert, frag):
        """
        compiles and links shaders
        :param vert: vertex shader source string
        :param frag: fragment shader source string
        :return:
        """
        # set the sources
        GL.glShaderSource(self._vertex, vert)
        GL.glShaderSource(self._fragment, frag)
        # compile vertex shader
        GL.glCompileShader(self._vertex)
        if not GL.glGetShaderiv(self._vertex, GL.GL_COMPILE_STATUS):
            e = GL.glGetShaderInfoLog(self._vertex).decode()
            raise VisualizationError(
                "Vertex shader couldn't be compiled:\n%s" % str(e),
                Level.CRITICAL)

        # compile fragment shader
        GL.glCompileShader(self._fragment)
        if not GL.glGetShaderiv(self._fragment, GL.GL_COMPILE_STATUS):
            e = GL.glGetShaderInfoLog(self._fragment).decode()
            raise VisualizationError(
                "Fragment shader couldn't be compiled:\n%s" % str(e),
                Level.CRITICAL)

        # attach the shaders to the matter program
        GL.glAttachShader(self._program, self._vertex)
        GL.glAttachShader(self._program, self._fragment)

        # link the shaders to the matter program
        GL.glLinkProgram(self._program)
        if not GL.glGetProgramiv(self._program, GL.GL_LINK_STATUS):
            e = GL.glGetProgramInfoLog(self._program)
            raise VisualizationError(
                "The shaders couldn't be linked to program:\n%s" % str(e),
                Level.CRITICAL)

        # detach the shaders from matter program
        GL.glDetachShader(self._program, self._vertex)
        GL.glDetachShader(self._program, self._fragment)
예제 #4
0
    def set_color(self, color: tuple):
        """
        Sets the matter color

        :param color: matter color
        :return: None
        """
        if len(color) != 4:
            raise VisualizationError(
                "Invalid color format!\ncolor has to be in rgba format => (float, float, float, float)", Level.WARNING)

        else:
            self.color = color
예제 #5
0
 def get_attribute_location(self, name: str):
     """
     gets and checks the attribute location with given name
     :param name: variable name (string)
     :return: location (int)
     """
     loc = GL.glGetAttribLocation(self._program, name)
     if loc < 0:
         raise VisualizationError(
             "Attribute \"%s\" doesn't exist!\n"
             "(Maybe the compilation optimized the shader by removing the unused attribute?)"
             % name, Level.WARNING)
     else:
         return loc
예제 #6
0
 def set_line_scaling(self, scaling):
     """
     sets the line_scaling uniform in the vertex shader
     :param scaling: the scaling vector
     :return:
     """
     self.use()
     gpu_data = np.array(scaling, dtype=np.float32).flatten()
     if len(gpu_data) != 3:
         raise VisualizationError(
             "Length of set_line_scaling parameter not correct, expected 3 got %d "
             % len(gpu_data), Level.WARNING)
     loc = self.get_uniform_location("line_scaling")
     GL.glUniform3f(loc, *gpu_data)
예제 #7
0
 def set_model_color(self, color):
     """
     sets the model_color uniform in the grid vertex shader
     :param color: the color (rgba)
     :return:
     """
     self.use()
     gpu_data = np.array(color, dtype=np.float32).flatten()
     if len(gpu_data) != 4:
         raise VisualizationError(
             "Length of set_model_color parameter not correct, expected 4 got %d "
             % len(gpu_data), Level.WARNING)
     loc = self.get_uniform_location("model_color")
     GL.glUniform4f(loc, *gpu_data)
예제 #8
0
 def set_light_color(self, light_color):
     """
     sets the color of the light
     :param light_color: tuple/array, rgba format
     :return:
     """
     self.use()
     gpu_data = np.array(light_color, dtype=np.float32).flatten()
     if len(gpu_data) != 4:
         raise VisualizationError(
             "Length of set_light_color parameter not correct, expected 4 got %d "
             % len(gpu_data), Level.WARNING)
     else:
         loc = self.get_uniform_location("light_color")
         GL.glUniform4f(loc, *light_color)
예제 #9
0
 def set_model_scaling(self, scaling):
     """
     sets the size scaling of the model
     :param scaling: 3d float tuple/array
     :return:
     """
     self.use()
     gpu_data = np.array(scaling, dtype=np.float32).flatten()
     if len(gpu_data) != 3:
         raise VisualizationError(
             "Length of set_model_scaling parameter not correct, expected 3 got %d "
             % len(gpu_data), Level.WARNING)
     else:
         loc = self.get_uniform_location("model_scaling")
         GL.glUniform3f(loc, *gpu_data)
예제 #10
0
 def set_world_matrix(self, world_matrix):
     """
     sets the world matrix in the vertex shader
     :param world_matrix: 4x4 float32
     :return:
     """
     self.use()
     gpu_data = np.array(world_matrix, dtype=np.float32).flatten()
     if len(gpu_data) != 16:
         raise VisualizationError(
             "Length of set_world_matrix parameter not correct, expected 16 got %d "
             % len(gpu_data), Level.WARNING)
     else:
         loc = self.get_uniform_location("world")
         GL.glUniformMatrix4fv(loc, 1, False, world_matrix)
예제 #11
0
 def set_projection_matrix(self, projection_matrix):
     """
     sets the projection matrix in the vertex shader program
     :param projection_matrix: 4x4 float32 projection matrix
     :return:
     """
     self.use()
     gpu_data = np.array(projection_matrix, dtype=np.float32).flatten()
     if len(gpu_data) != 16:
         raise VisualizationError(
             "Length of set_projection_matrix parameter not correct, expected 16 got %d "
             % len(gpu_data), Level.CRITICAL)
     else:
         loc = self.get_uniform_location("projection")
         GL.glUniformMatrix4fv(loc, 1, False, projection_matrix)
예제 #12
0
 def update_previous_positions(self, data):
     """
     updates the previous positions data (VBO 3)
     :param data: array of 3d positions
     """
     self.use()
     gpu_data = np.array(data, dtype=np.float32).flatten()
     GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbos[3])
     GL.glBufferData(GL.GL_ARRAY_BUFFER, gpu_data.nbytes, gpu_data,
                     GL.GL_DYNAMIC_DRAW)
     if len(gpu_data) % 3.0 != 0.0:
         raise VisualizationError(
             "Invalid previous positions data! Amount of coordinate "
             "components not dividable by 3 (not in xyz format?)!",
             Level.WARNING)
예제 #13
0
 def update_colors(self, data):
     """
     updates the color data (VBO2)
     :param data: list/array of rgba values. (dimensions are irrelevant)
     :return:
     """
     self.use()
     gpu_data = np.array(data, dtype=np.float32).flatten()
     GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbos[2])
     GL.glBufferData(GL.GL_ARRAY_BUFFER, gpu_data.nbytes, gpu_data,
                     GL.GL_DYNAMIC_DRAW)
     if len(gpu_data) % 4.0 != 0.0:
         raise VisualizationError(
             "Invalid color data! Amount of color components not dividable by 4 (not in rgba format?)!",
             Level.WARNING)
예제 #14
0
 def _update_projection(self):
     if self._projection_type == "perspective":
         self.projection_matrix = get_perspetive_projection_matrix(
             self._fov, self._aspect, 1, self._render_distance)
     elif self._projection_type == "ortho":
         self.projection_matrix = get_orthographic_projection_matrix(
             -self._radius * self._aspect, self._radius * self._aspect,
             -self._radius, self._radius, 0.001, self._render_distance)
     else:
         self._projection_type = "perspective"
         self.projection_matrix = get_perspetive_projection_matrix(
             self._fov, self._aspect, 1, self._render_distance)
         raise VisualizationError(
             "Unknown projection type: \"" + self._projection_type +
             "\"! Setting projection to perspective.", Level.INFO)
예제 #15
0
 def update_offsets(self, data):
     """
     updates the offsets/positions data (VBO 1)
     :param data: array of 3d positions
     :return:
     """
     self.use()
     gpu_data = np.array(data, dtype=np.float32).flatten()
     GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbos[1])
     GL.glBufferData(GL.GL_ARRAY_BUFFER, gpu_data.nbytes, gpu_data,
                     GL.GL_DYNAMIC_DRAW)
     self.amount = len(gpu_data) / 3.0
     if len(gpu_data) % 3.0 != 0.0:
         raise VisualizationError(
             "Invalid offset data! Amount of coordinate components not dividable by 3 (not in xyz format?)!",
             Level.WARNING)
     self.amount = int(self.amount)