Esempio n. 1
0
class Canvas(QGLWidget):
    def __init__(self, imgPath=None):
        QGLWidget.__init__(self)

        self.layers = []
        self.canvasWidth = 640 # size of image, not entire widget
        self.canvasHeight = 480

        if imgPath is None:
            self.imgPath = None
            self.setWindowTitle('untitled*')
        else:
            if not os.path.exists(imgPath):
                raise IOError

            self.imgPath = imgPath
            self.startImg = QImage()
            self.startImg.load(self.imgPath)
            self.canvasWidth = self.startImg.width()
            self.canvasHeight = self.startImg.height()
            
            self.setWindowTitle(imgPath)

    def mousePressEvent(self, event):
        #print('press')
        self.paintGL()

    def mouseReleaseEvent(self, event):
        print('release')

    def mouseMoveEvent(self, event):
        #print('move')
        self.paintGL()

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT)

        # draw FBO layers from the bottom up
        for layer in reversed(self.layers):
            self.drawTexture(QPointF(0,0), layer.texture(), GL_TEXTURE_RECTANGLE_ARB)

        # if stroke, draw to the stroke layer, draw stroke layer
        self.program.bind()
        glBegin(GL_LINE_STRIP)
        g=gluNewNurbsRenderer()
        x1 = y1 = 25
        x2 = y2 = 450
        scale = abs(x2-x1)/3.0
        midx, midy = (abs(x2+x1)/2.0), abs(y2+y1)/2.0   
        degree = 3

            
        ctrlpoints=[[x1, y1, 0],
            [x1+scale, y1, 0],
            [midx, midy, 0],
            [x2-scale, y2, 0],
            [x2, y2, 0]]   
        
        glu.gluBeginCurve(g)
        glu.gluNurbsCurve(g,
                          [[10,10,0],[50,30,0],[100,100,0],[110,220,0],[400,280,0]],
                          [[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],[0,0,0.1,0.1],],
                          GL_MAP1_VERTEX_3)
        glu.gluEndCurve(g)
        
        glVertex2f(10,10)
        glVertex2f(20,10)
        glVertex2f(10,200)
        glVertex2f(100,200)
        
        glEnd()
        self.program.release()
        

    def resizeGL(self, w, h):
        glViewport(0,0,w,h)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, w, 0, h, -1, 1)

    def initializeGL(self):
        glClearColor(0.4, 0.4, 0.4, 1.0)

        # if a starting image, load it
#        if self.startImg is not None:
#            print(self.img.width())

        self.layers = [ Layer(self.canvasWidth,self.canvasHeight) ]
        self.strokeLayer = Layer(self.canvasWidth,self.canvasHeight)

        # if there's a starting image, draw it into the starting layer
        if self.imgPath is not None:
            bottomLayer = self.layers[-1]
            bottomLayer.bind()

            # setup the orthographic projection and viewport
            glMatrixMode(GL_PROJECTION)
            glPushMatrix()
            glLoadIdentity()
            glOrtho(0, self.canvasWidth, 0, self.canvasHeight, -1, 1)
            glViewport(0, 0, self.canvasWidth, self.canvasHeight)
            

            imgTextureId = self.bindTexture(self.startImg, GL_TEXTURE_RECTANGLE_ARB)
            self.drawTexture(QPointF(0,0), imgTextureId, GL_TEXTURE_RECTANGLE_ARB)

            self.deleteTexture(imgTextureId)

            # restore the previous projection matrix and viewport
            glMatrixMode(GL_PROJECTION)
            glPopMatrix()
            glViewport(0, 0, self.width(), self.height()) # should be saved off?

            bottomLayer.release()

            self.startImg = None

        # setup the necessary shaders
        self.program = ShaderProgram()
        self.program.attachShader(ShaderCode(GL_VERTEX_SHADER,'./shaders/basic.vert'))
        self.program.attachShader(ShaderCode(GL_FRAGMENT_SHADER,'./shaders/basic.frag'))