Пример #1
0
 def prepare_rendering(self, render_option):
     if render_option.primitive == renderoption.Primitive.Point:
         gl.glPointSize(gl.GLfloat(render_option.point_size))
     else:
         gl.glLineWidth(gl.GLfloat(render_option.line_width))
     gl.glEnable(gl.GL_DEPTH_TEST)
     gl.glDepthFunc(gl.GLenum(render_option.get_depth_func()))
     return True
Пример #2
0
 def prepare_rendering(self, render_option):
     if render_option.primitive.Line:
         gl.glLineWidth(gl.GLfloat(2.0))
     else:
         gl.glPointSize(gl.GLfloat(5.0))
     gl.glEnable(gl.GL_DEPTH_TEST)
     gl.glDepthFunc(gl.GLenum(gl.GL_LEQUAL))
     return True
Пример #3
0
    def render(self):
        """Handle all drawing operations."""
        self.SetCurrent(self.context)
        if not self.init:
            # Configure the viewport, modelview and projection matrices
            self.init_gl()
            self.init = True

        # Clear everything
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        # Generate trace vertices for each monitor.
        if self.devices is not None:
            self._gen_trace()
            # Draw trace for each monitor.
            for i, key in enumerate(self.monitors.monitors_dictionary.keys()):
                # Shade trace in a color corresponding to device type
                device_id = key[0]
                if self.devices is not None:
                    color = self.devices.get_device(device_id).device_kind
                    GL.glColor4f(*self.color_dict[color])
                    GL.glBegin(GL.GL_QUADS)
                    for q in self.quads[i]:
                        x, y = q
                        GL.glVertex2f(x, y)
                    GL.glEnd()
                    GL.glColor3f(0.0, 0.0, 1.0)
                    GL.glLineWidth(GL.GLfloat(3))
                    # GL_LINES differs from GL_LINE_STRIP, in that
                    # lines are only created between pairs of vertices.
                    GL.glBegin(GL.GL_LINES)
                    for k in self.traces[i]:
                        x, y = k
                        GL.glVertex2f(x, y)
                    GL.glEnd()
        # We have been drawing to the back buffer, flush the graphics pipeline
        # and swap the back buffer to the front
        GL.glFlush()
        self.SwapBuffers()
Пример #4
0
    def render(self):

        self.framebufferObject().setAttachment(
            QOpenGLFramebufferObject.CombinedDepthStencil)

        e = GL.glGetError()  #clear any pending errors

        c = self.background_color
        GL.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glBlendEquation(GL.GL_FUNC_ADD)
        GL.glEnable(GL.GL_PRIMITIVE_RESTART)

        GL.glPrimitiveRestartIndex(0xFFFFFFFF)
        GL.glDrawBuffers(len(self.draw_buffers), self.draw_buffers)

        #opengl_error_check(currentframe())

        if self.render_to_texture_attachment != -1:

            GL.glFramebufferTexture2D(
                GL.GL_FRAMEBUFFER,
                self.draw_buffers[self.render_to_texture_attachment],
                GL.GL_TEXTURE_2D,
                self.locked_render_to_texture_array.___tex___.textureId(), 0)

            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

            if GL.glCheckFramebufferStatus(
                    GL.GL_FRAMEBUFFER) != GL.GL_FRAMEBUFFER_COMPLETE:
                raise RuntimeError("glCheckFramebufferStatus() problem")

        #opengl_error_check(currentframe())

        for actor in self.bo_actors:
            try:
                program = actor['program']
                indices = actor['indices']
                attribs = actor['attribs']
                textures = actor['textures']
                out_textures = actor['out_textures']
                transform = actor['transform']
                uniforms = actor['uniforms']
                primitiveType = actor['primitiveType']
                point_size = actor['point_size']
                line_width = actor['line_width']

                program.bind()

                self.vertex_array.bind()

                for name, bo in viewitems(attribs):
                    if bo is None:
                        continue
                    bo.bind()
                    loc = program.attributeLocation(name)
                    program.enableAttributeArray(loc)

                    dim = bo.shape[1] if len(bo.shape) > 1 else 1

                    if bo.dtype == np.float32:
                        program.setAttributeBuffer(loc, GL.GL_FLOAT, 0, dim)
                    elif bo.dtype == np.int32:
                        program.setAttributeBuffer(loc, GL.GL_INT, 0, dim)
                    else:
                        raise ValueError(
                            f'Unsupported dtype {bo.dtype} for attrib {name}')

                #opengl_error_check(currentframe())

                m = transform
                v = self.view_matrix
                p = self.perspective_matrix

                if program.uniformLocation("matrix") == -1:
                    program.setUniformValue("model_matrix", m)
                    program.setUniformValue("view_matrix", v)
                    program.setUniformValue("projection_matrix", p)
                    program.setUniformValue("normal_matrix", m.normalMatrix())
                    program.setUniformValue("view_matrix_inv", v.inverted()[0])
                else:
                    program.setUniformValue("matrix", p * v * m)

                if program.uniformLocation("ortho_matrix") != -1:
                    program.setUniformValue("ortho_matrix",
                                            self.orthographic_matrix)

                if program.uniformLocation("aspect_ratio") != -1:
                    program.setUniformValue(
                        "aspect_ratio",
                        self.viewport_width / self.viewport_height)

                #opengl_error_check(currentframe())

                if program.uniformLocation("point_size") != -1:
                    GL.glDisable(GL.GL_PROGRAM_POINT_SIZE)
                    program.setUniformValue("point_size", float(point_size))
                elif point_size != 1:
                    try:
                        GL.glEnable(GL.GL_PROGRAM_POINT_SIZE)
                        GL.glPointSize(GL.GLfloat(point_size))
                    except Exception as e:
                        # glPointSize is refused by the driver
                        LoggingManager.instance().warning(
                            f"glPointSize failed with: exception {e}")

                #opengl_error_check(currentframe())

                for name, value in viewitems(uniforms):
                    program.setUniformValue(name, value)
                    #opengl_error_check(currentframe(), f"error with uniform {name}, {value}")

                texture_unit = 0
                for name, tex in viewitems(textures):
                    tex.bind(texture_unit)
                    program.setUniformValue(name, texture_unit)
                    #opengl_error_check(currentframe(), f"error with texture {name}, {value}")
                    texture_unit += 1

                for name, tex in viewitems(out_textures):
                    if tex is None:
                        LoggingManager.instance().warning(
                            f'output texture {name} is null')
                        continue

                    # in your fragment shader, you can specify the location via the layout decoration
                    # e.g. layout(location = 1) out vec4 my_output;
                    loc = GL.glGetFragDataLocation(program.programId(), name)

                    GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
                                              self.get_texture_attachment(loc),
                                              GL.GL_TEXTURE_2D,
                                              tex.textureId(), 0)

                    if GL.glCheckFramebufferStatus(
                            GL.GL_FRAMEBUFFER) != GL.GL_FRAMEBUFFER_COMPLETE:
                        raise RuntimeError(
                            "glCheckFramebufferStatus() problem")

                #opengl_error_check(currentframe())

                if line_width != 1:
                    try:
                        GL.glEnable(GL.GL_LINE_SMOOTH)
                        #opengl_error_check(currentframe())
                        GL.glLineWidth(GL.GLfloat(line_width))
                    except Exception as e:
                        aliased_r = (GL.GLfloat * 2)()
                        GL.glGetFloatv(GL.GL_ALIASED_LINE_WIDTH_RANGE,
                                       aliased_r)
                        smooth_r = (GL.GLfloat * 2)()
                        GL.glGetFloatv(GL.GL_SMOOTH_LINE_WIDTH_RANGE, smooth_r)
                        line_r = (GL.GLfloat * 2)()
                        GL.glGetFloatv(GL.GL_LINE_WIDTH_RANGE, line_r)
                        LoggingManager.instance().warning(
                            f"{e}: yout asked for line_width = {line_width}, line range is {list(line_r)}, aliased range is {list(aliased_r)}, smooth range is {list(smooth_r)}"
                        )
                else:
                    GL.glDisable(GL.GL_LINE_SMOOTH)

                #opengl_error_check(currentframe())

                if indices is not None and indices.shape[0] > 0:
                    indices.bind()
                    GL.glDrawElements(primitiveType, indices.shape[0],
                                      GL.GL_UNSIGNED_INT, None)
                    indices.release()
                elif attribs["vertices"].shape[0] > 0:
                    GL.glDrawArrays(primitiveType, 0,
                                    attribs["vertices"].shape[0])

                for name, bo in viewitems(attribs):
                    if bo is not None:
                        bo.release()
                        program.disableAttributeArray(name)

                for name, tex in viewitems(textures):
                    if tex is not None:
                        tex.release()

                for name, tex in viewitems(out_textures):
                    if tex is not None:
                        tex.release()

                for name, tex in viewitems(out_textures):
                    shape = tex.shape
                    tex.bind()
                    loc = GL.glGetFragDataLocation(program.programId(), name)
                    GL.glReadBuffer(self.get_texture_attachment(loc))

                    if shape[2] == 4:
                        if tex.dtype == np.uint8:
                            pixels = GL.glReadPixels(
                                0, 0, shape[0], shape[1], GL.GL_RGBA,
                                GL.GL_UNSIGNED_INT_8_8_8_8)
                            self.out_textures[tex] = pixels.view(
                                np.uint8).reshape(shape[1], shape[0], 4)
                        elif tex.dtype == np.float32:
                            pixels = GL.glReadPixels(0, 0, shape[0], shape[1],
                                                     GL.GL_RGBA, GL.GL_FLOAT)
                            self.out_textures[tex] = pixels

                    tex.release()

            except Exception as e:
                LoggingManager.instance().warning(traceback.format_exc())
            finally:
                self.vertex_array.release()
                program.release()

        if self.render_to_texture_attachment != -1:
            shape = self.locked_render_to_texture_array.ndarray.shape
            self.locked_render_to_texture_array.___tex___.bind()
            GL.glReadBuffer(
                self.draw_buffers[self.render_to_texture_attachment])
            r = GL.glReadPixels(0, 0, shape[0], shape[1], GL.GL_RGBA,
                                GL.GL_UNSIGNED_INT_8_8_8_8)
            self.locked_render_to_texture_array.___tex___.release()
            self.locked_render_to_texture_array.ndarray = np.flipud(
                r.view(np.uint8).reshape(shape[1], shape[0], 4)[..., ::-1])

        self.update()