Exemple #1
0
class TestCanvas(Canvas):

    def __init__(self):

        with open("vertex.glsl","r") as f:
            self.vertexShaderSource = f.read()

        with open("fragment.glsl","r") as f:
            self.fragmentShaderSource = f.read()

        if self.vertexShaderSource is None:
            raise Exception("Could not load the source for the vertex shader")

        if self.fragmentShaderSource is None:
            raise Exception("Could not load the source for the fragment shader")

        super(TestCanvas,self).__init__()

    def setupGL(self):

        self.program = QOpenGLShaderProgram(self.context())
        info("PROGRAM",self.program)

        # addShaderFromSourceCode() only returns a bool telling whether everything went well

        if self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, self.vertexShaderSource):
            info("VERTEX SHADER","Managed to load and parse the vertex shader")

        if self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, self.fragmentShaderSource):
            info("FRAGMENT SHADER","Managed to load and parse the fragment shader")

        # Compile and bind the shader program to the current context
        self.program.link()
        self.program.bind()

        # Bind the shader attribute to a python variable
        self.somePosition = self.gl.glGetAttribLocation(self.program.programId(), "somePosition")

        # Tell GL that whenever we run glClear, this is the color that
        # should be used. We only need to do this once. 
        self.gl.glClearColor(0.1, 0.1, 0.1, 1.0)

        self.dumpGLLogMessages("setupGL()")

    def paintGL(self):
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
        
        # Assign a value to the shader parameter
        self.gl.glVertexAttrib3f(self.somePosition, 0.5, 0.5, 0.0)

        # Mode, starting at vertex number, number of vertices to draw
        self.gl.glDrawArrays(self.gl.GL_POINTS,0,1)

        self.dumpGLLogMessages("paintGL()")

    def resizeGL(self, width, height):
        pass
class TestCanvas(Canvas):
    def __init__(self):

        with open("vertex.glsl", "r") as f:
            self.vertexShaderSource = f.read()

        with open("fragment.glsl", "r") as f:
            self.fragmentShaderSource = f.read()

        if self.vertexShaderSource is None:
            raise Exception("Could not load the source for the vertex shader")

        if self.fragmentShaderSource is None:
            raise Exception(
                "Could not load the source for the fragment shader")

        super(TestCanvas, self).__init__()

    def setupGL(self):

        self.program = QOpenGLShaderProgram(self.context())
        info("PROGRAM", self.program)

        # addShaderFromSourceCode() only returns a bool telling whether everything went well

        if self.program.addShaderFromSourceCode(QOpenGLShader.Vertex,
                                                self.vertexShaderSource):
            info("VERTEX SHADER",
                 "Managed to load and parse the vertex shader")

        if self.program.addShaderFromSourceCode(QOpenGLShader.Fragment,
                                                self.fragmentShaderSource):
            info("FRAGMENT SHADER",
                 "Managed to load and parse the fragment shader")

        # Compile and bind the shader program to the current context
        self.program.link()
        self.program.bind()

        # Bind the shader attribute to a python variable
        self.somePosition = self.gl.glGetAttribLocation(
            self.program.programId(), "somePosition")

        # Use array rather than list in order to get control over actual data size
        self.vertices = array.array(
            'f',
            [-0.5, -0.5, 0.0, 0.5, 0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0])

        # Buffer info returns a tuple where the second part is number of elements in the array
        self.verticesLength = self.vertices.buffer_info()[1]

        # Size in bytes for each element
        self.verticesItemSize = self.vertices.itemsize

        # Total size in bytes for entire array
        self.verticesDataLength = self.verticesLength * self.verticesItemSize

        # Number of vertices in the array
        self.numberOfVertices = int(self.verticesLength / 3)

        # Tell gl to prepare a buffer
        self.vertexBuffer = self.gl.glGenBuffers(1)

        # Say that the buffer is of type GL_ARRAY_BUFFER
        self.gl.glBindBuffer(self.gl.GL_ARRAY_BUFFER, self.vertexBuffer)

        # Copy data into the buffer
        self.gl.glBufferData(self.gl.GL_ARRAY_BUFFER, self.verticesDataLength,
                             self.vertices.tobytes(), self.gl.GL_STATIC_DRAW)

        # Say that the somePosition attribute should be read from the current array, that it should take three values at a
        # time (x, y, z), and that they are of the type GL_FLOAT
        self.gl.glVertexAttribPointer(self.somePosition, 3, self.gl.GL_FLOAT,
                                      False, 0, 0)

        # When reading from the current data, start at position 0
        self.gl.glEnableVertexAttribArray(0)

        # Tell GL that whenever we run glClear, this is the color that
        # should be used. We only need to do this once.
        self.gl.glClearColor(0.1, 0.1, 0.1, 1.0)

        self.dumpGLLogMessages("setupGL()")

    def paintGL(self):
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT
                        | self.gl.GL_DEPTH_BUFFER_BIT)

        # Draw points, starting at vertex number, number of vertices to draw. Since we enabled attribarrays, it will
        # fetch data from the array buffer
        self.gl.glDrawArrays(self.gl.GL_POINTS, 0, self.numberOfVertices)

        self.dumpGLLogMessages("paintGL()")

    def resizeGL(self, width, height):
        pass
class TestCanvas(Canvas):
    def __init__(self):

        with open("vertex.glsl", "r") as f:
            self.vertexShaderSource = f.read()

        with open("fragment.glsl", "r") as f:
            self.fragmentShaderSource = f.read()

        if self.vertexShaderSource is None:
            raise Exception("Could not load the source for the vertex shader")

        if self.fragmentShaderSource is None:
            raise Exception(
                "Could not load the source for the fragment shader")

        # Use an initial scale assuming width = height (should always be overwritten
        # in the resizeGL method below)
        self.currentScaling = QVector4D(1.0, 1.0, 1.0, 1.0)

        super(TestCanvas, self).__init__()

    # Use a non-square initial size
    def sizeHint(self):
        info("TESTCANVAS", "using overridden sizeHint()")
        return QSize(600, 600)

    def setupGL(self):

        self.program = QOpenGLShaderProgram(self.context())
        info("PROGRAM", self.program)

        # addShaderFromSourceCode() only returns a bool telling whether everything went well

        if self.program.addShaderFromSourceCode(QOpenGLShader.Vertex,
                                                self.vertexShaderSource):
            info("VERTEX SHADER",
                 "Managed to load and parse the vertex shader")

        if self.program.addShaderFromSourceCode(QOpenGLShader.Fragment,
                                                self.fragmentShaderSource):
            info("FRAGMENT SHADER",
                 "Managed to load and parse the fragment shader")

        # Compile and bind the shader program to the current context
        self.program.link()
        self.program.bind()

        # Bind the shader attribute for transfering vertex positions to a python variable
        self.somePosition = self.gl.glGetAttribLocation(
            self.program.programId(), "somePosition")

        # Bind the shader attribute for transfering vertex colors to a python variable
        self.inputColor = self.gl.glGetAttribLocation(self.program.programId(),
                                                      "inputColor")

        # Bind the shader "uniform" for controling the viewport scale of the vertex positions
        self.viewportScaling = self.gl.glGetUniformLocation(
            self.program.programId(), "viewportScaling")

        # Bind the shader "uniform" for controling the rotation of the object
        self.objectRotation = self.gl.glGetUniformLocation(
            self.program.programId(), "objectRotation")

        # Here we mix vertex data (x, y, z) with color data (r, g, b, a).
        self.vertices = array.array(
            'f',
            [
                -0.5,
                -0.5,
                0.0,
                1.0,
                0.0,
                0.0,
                1.0,  # Bottom left is red
                -0.5,
                0.5,
                0.0,
                0.0,
                1.0,
                0.0,
                1.0,  # Top left is green
                0.5,
                0.5,
                0.0,
                0.0,
                0.0,
                1.0,
                1.0,  # Top right is blue
                0.5,
                -0.5,
                0.0,
                1.0,
                1.0,
                0.0,
                1.0  # Bottom right is yellow
            ])

        # Buffer info returns a tuple where the second part is number of elements in the array
        self.verticesLength = self.vertices.buffer_info()[1]

        # Each vertex is specified with with seven values (xyzrgba)
        self.arrayCellsPerVertex = 7

        # Size in bytes for each vertex specification (self.vertices.itemsize is the size in bytes
        # of a single array cell)
        self.vertexSpecificationSize = self.vertices.itemsize * self.arrayCellsPerVertex

        # In bytes, where in a vertex specification does the color data start? (it starts after
        # x, y, z.. i.e after 3 array cells)
        self.colorBytesOffset = self.vertices.itemsize * 3

        # Total size in bytes for entire array
        self.verticesDataLength = self.verticesLength * self.vertices.itemsize

        # Number of vertices in the array
        self.numberOfVertices = int(self.verticesLength /
                                    self.arrayCellsPerVertex)

        # Tell gl to prepare a single buffer
        self.vertexBuffer = self.gl.glGenBuffers(1)

        # Say that the buffer is of type GL_ARRAY_BUFFER
        self.gl.glBindBuffer(self.gl.GL_ARRAY_BUFFER, self.vertexBuffer)

        # Copy data into the buffer
        self.gl.glBufferData(self.gl.GL_ARRAY_BUFFER, self.verticesDataLength,
                             self.vertices.tobytes(), self.gl.GL_STATIC_DRAW)

        # Say that the somePosition attribute should be read from the current array, that it should take three values at a
        # time (x, y, z), and that they are of the type GL_FLOAT. We now also specify a byte offset (vertexSpecificationSize)
        # to say that each new vertex specification is starting this many bytes after the prior one.
        self.gl.glVertexAttribPointer(self.somePosition, 3, self.gl.GL_FLOAT,
                                      False, self.vertexSpecificationSize, 0)

        # Connect the array to the somePosition variable
        self.gl.glEnableVertexAttribArray(self.somePosition)

        # Say that the inputColor attribute should be read from the current array, that it should take four values at a
        # time (r, g, b, a), and that they are of type GL_FLOAT. The same byte offset as for the position info is used, but
        # we now also specify that the color information starts at colorBytesOffset bytes into each vertex specification
        self.gl.glVertexAttribPointer(self.inputColor, 4, self.gl.GL_FLOAT,
                                      False, self.vertexSpecificationSize,
                                      self.colorBytesOffset)

        # Connect the array to the inputColor variable
        self.gl.glEnableVertexAttribArray(self.inputColor)

        # Tell GL that whenever we run glClear, this is the color that
        # should be used. We only need to do this once.
        self.gl.glClearColor(0.1, 0.1, 0.1, 1.0)

        self.dumpGLLogMessages("setupGL()")

    def paintGL(self):
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT
                        | self.gl.GL_DEPTH_BUFFER_BIT)

        # Set rotation so that the quad is rotated 45 degrees clockwise
        self.currentRotation = QVector3D(0.0, 0.0, 45.0)
        self.program.setUniformValue(self.objectRotation, self.currentRotation)

        # Before painting we set the scaling "uniform" parameter in the vertex shader.
        # This will be used to scale the vertex positions.
        self.program.setUniformValue(self.viewportScaling, self.currentScaling)

        # Draw a quad starting at vertex number. Since we enabled attribarrays, it will fetch data from the array buffer
        self.gl.glDrawArrays(self.gl.GL_QUADS, 0, self.numberOfVertices)

        self.dumpGLLogMessages("paintGL()")

    def resizeGL(self, width, height):
        scaleX = 1.0
        scaleY = 1.0
        scaleZ = 1.0  # Will always be 1.0 since we don't scale depth
        scaleW = 1.0  # A global scale factor, also always 1.0

        if width > height:
            scaleX = height / width
        else:
            scaleY = width / height

        self.currentScaling = QVector4D(scaleX, scaleY, scaleZ, scaleW)

        # Redraw since we changed the value of the scaling uniform
        self.update()
Exemple #4
0
class TestCanvas(Canvas):
    def __init__(self):

        with open("vertex.glsl", "r") as f:
            self.vertexShaderSource = f.read()

        with open("fragment.glsl", "r") as f:
            self.fragmentShaderSource = f.read()

        if self.vertexShaderSource is None:
            raise Exception("Could not load the source for the vertex shader")

        if self.fragmentShaderSource is None:
            raise Exception(
                "Could not load the source for the fragment shader")

        super(TestCanvas, self).__init__()

    def setupGL(self):

        self.program = QOpenGLShaderProgram(self.context())
        info("PROGRAM", self.program)

        # addShaderFromSourceCode() only returns a bool telling whether everything went well

        if self.program.addShaderFromSourceCode(QOpenGLShader.Vertex,
                                                self.vertexShaderSource):
            info("VERTEX SHADER",
                 "Managed to load and parse the vertex shader")

        if self.program.addShaderFromSourceCode(QOpenGLShader.Fragment,
                                                self.fragmentShaderSource):
            info("FRAGMENT SHADER",
                 "Managed to load and parse the fragment shader")

        # Compile and bind the shader program to the current context
        self.program.link()
        self.program.bind()

        # Bind the shader attribute for transfering vertex positions to a python variable
        self.somePosition = self.gl.glGetAttribLocation(
            self.program.programId(), "somePosition")

        # Bind the shader attribute for transfering vertex colors to a python variable
        self.inputColor = self.gl.glGetAttribLocation(self.program.programId(),
                                                      "inputColor")

        # Here we mix vertex data (x, y, z) with color data (r, g, b, a).
        self.vertices = array.array(
            'f',
            [
                -0.5,
                -0.5,
                0.0,
                1.0,
                0.0,
                0.0,
                1.0,  # Bottom left is red
                -0.5,
                0.5,
                0.0,
                0.0,
                1.0,
                0.0,
                1.0,  # Top left is green
                0.5,
                0.5,
                0.0,
                0.0,
                0.0,
                1.0,
                1.0,  # Top right is blue
                0.5,
                -0.5,
                0.0,
                1.0,
                1.0,
                0.0,
                1.0  # Bottom right is yellow
            ])

        # Buffer info returns a tuple where the second part is number of elements in the array
        self.verticesLength = self.vertices.buffer_info()[1]

        # Each vertex is specified with with seven values (xyzrgba)
        self.arrayCellsPerVertex = 7

        # Size in bytes for each vertex specification (self.vertices.itemsize is the size in bytes
        # of a single array cell)
        self.vertexSpecificationSize = self.vertices.itemsize * self.arrayCellsPerVertex

        # In bytes, where in a vertex specification does the color data start? (it starts after
        # x, y, z.. i.e after 3 array cells)
        self.colorBytesOffset = self.vertices.itemsize * 3

        # Total size in bytes for entire array
        self.verticesDataLength = self.verticesLength * self.vertices.itemsize

        # Number of vertices in the array
        self.numberOfVertices = int(self.verticesLength /
                                    self.arrayCellsPerVertex)

        # Tell gl to prepare a single buffer
        self.vertexBuffer = self.gl.glGenBuffers(1)

        # Say that the buffer is of type GL_ARRAY_BUFFER
        self.gl.glBindBuffer(self.gl.GL_ARRAY_BUFFER, self.vertexBuffer)

        # Copy data into the buffer
        self.gl.glBufferData(self.gl.GL_ARRAY_BUFFER, self.verticesDataLength,
                             self.vertices.tobytes(), self.gl.GL_STATIC_DRAW)

        # Say that the somePosition attribute should be read from the current array, that it should take three values at a
        # time (x, y, z), and that they are of the type GL_FLOAT. We now also specify a byte offset (vertexSpecificationSize)
        # to say that each new vertex specification is starting this many bytes after the prior one.
        self.gl.glVertexAttribPointer(self.somePosition, 3, self.gl.GL_FLOAT,
                                      False, self.vertexSpecificationSize, 0)

        # Connect the array to the somePosition variable
        self.gl.glEnableVertexAttribArray(self.somePosition)

        # Say that the inputColor attribute should be read from the current array, that it should take four values at a
        # time (r, g, b, a), and that they are of type GL_FLOAT. The same byte offset as for the position info is used, but
        # we now also specify that the color information starts at colorBytesOffset bytes into each vertex specification
        self.gl.glVertexAttribPointer(self.inputColor, 4, self.gl.GL_FLOAT,
                                      False, self.vertexSpecificationSize,
                                      self.colorBytesOffset)

        # Connect the array to the inputColor variable
        self.gl.glEnableVertexAttribArray(self.inputColor)

        # Tell GL that whenever we run glClear, this is the color that
        # should be used. We only need to do this once.
        self.gl.glClearColor(0.1, 0.1, 0.1, 1.0)

        self.dumpGLLogMessages("setupGL()")

    def paintGL(self):
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT
                        | self.gl.GL_DEPTH_BUFFER_BIT)

        # Draw a quad starting at vertex number. Since we enabled attribarrays, it will fetch data from the array buffer
        self.gl.glDrawArrays(self.gl.GL_QUADS, 0, self.numberOfVertices)

        self.dumpGLLogMessages("paintGL()")

    def resizeGL(self, width, height):
        pass