2019年7月12日金曜日

opengl(pyopengl)マウスのドラッグで線をひく ラバーバンド





mouse_drag.py

#coding:utf-8
#2010/05/17 19:53〜
#[2019-07-11]

#参考サイト
#GLUTによる「手抜き」OpenGL入門
# http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#4

#drag_sen.png

#@@@
#動作
#マウスのドラッグで線をひく
#前のプログラムでは, マウスの左ボタンを押してから離すまでウィンドウには
#何も表示されませんでした. これを, マウスのドラッグ中は線分をマウスに追
#従して描くようにします. このような効果をラバーバンド (輪ゴム) と言います
#. このために glutMotionFunc() を使って, マウスのドラッグ中にラバーバン
#ドを表示するようにします
#mouse_drag_two.pyとコード同じ
#正常に動作する
#motionあたりの動作が不明 glLogicOp(GL_INVERT)がわからん
#rubberband->flg_downに変える
#@@@


from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

MAXPOINTS=100   #記憶する点の数
point = [[0, 0]]*MAXPOINTS  #座標を記憶する配列
pointnum=0      #記憶した座標の数
flg_down=0  #マウスがdownになると1
savepoint = [0,0]

def display():
    glClear(GL_COLOR_BUFFER_BIT)
    ## 記憶したデータで線を描く
    if pointnum>1:
        glColor3d(0.0, 0.0, 0.0)
        glBegin(GL_LINES)
        for p in point:
            glVertex2iv(p)
        glEnd()
    glFlush()

def resize(w, h):
    glViewport(0,0,w,h)
    #ウィンドウ全体をビューポートにする
    print w,h
    glLoadIdentity()
    # スクリーン上の座標系をマウスの座標系に一致させる
    glOrtho(-0.5, w-0.5, h -0.5, -0.5, -1.0, 1.0)


#global flg_down を入れないと線の終点が次の始点となり
#線が続く
def mouse(button, state, x, y):
    global point
    global pointnum
    global flg_down
    if button == GLUT_LEFT_BUTTON:
        if state == GLUT_DOWN:
            flg_down = 1
            point[pointnum] = [x, y]
        if state == GLUT_UP:
            if pointnum < MAXPOINTS-1:
                #up でインクリメントされる
                pointnum +=1
            point[pointnum] = [x, y]

            if pointnum < MAXPOINTS-1:
                #up でインクリメントされる
                pointnum +=1


#motion関数は基本的にupになるまで始点から終点までを線を引いては
#その線を消す動作をしている。
#ドラッグからupに移行すると、線を消す動作がはいらずmotion
#関数からでる。
"""
そこでラバーバンドを描く際には, 線を背景とは異なる色で描く代わりに,
描こうとする線上の画素の色を反転するようにします. こうすればもう一度同
じ線上の画素の色を反転することで, そこに描かれていた以前の線が消えてウィ
ンドウに描かれた図形が元に戻ります. このために glLogicOp() を使用しま
す. glLogicOp() で指定した論理演算は, glEnable(GL_LOGIC_OP)<白黒の場
合>あるいは glEnable(GL_COLOR_LOGIC_OP)<カラーの場合>で有効になりま

"""
def motion(x, y):
    global savepoint    # 以前のラバーバンドの端点 を記憶する
    global flg_down

    # 反転という論理演算を行うようにする?
    ## 論理演算機能 ON
    #  ウィンドウに既に描かれている内容と これから描こうとする内容
    # の間で論理演算を行うようにする
    glEnable(GL_COLOR_LOGIC_OP)
    # 以下の行のコマンドで ウィンドウに描かれている内容の これから
    # 描く図形の領域を反転します
    glLogicOp(GL_INVERT)

    #上のglEnable,glLogicOpの動作により「消す」以下の最初の描画コード
    #は描画の色が反転されて?消える。
    #「描く」以下の2番めの描画コードは通常描画される。
    #マウスをdownした時前のsavepointから今のマウスdownした位置まで
    #線をひくためsavepoint = point[pointnum]とする
    glBegin(GL_LINES)
    if flg_down == 1:
        savepoint = point[pointnum]
    ##以前のラバーバンドを消す
    glVertex2iv(point[pointnum])
    glVertex2iv(savepoint)
    #新しいラバーバンドを描く 
    print "描く"
    glVertex2iv(point[pointnum])
    glVertex2i(x,y)
    glEnd()
    glFlush()

    #以下のコマンドもなくても動作する
    ### 論理演算機能OFF
    ##GL_COPY はこれから描こうとする内容をそのままウィンドウ内に描きます
    #glLogicOp(GL_COPY)
    ##引数  に指定した機能を使用不可にします
    #glDisable(GL_COLOR_LOGIC_OP)

    #今描いたラバーバンドの端点を保存
    savepoint = [x,y]
    #端点をあらたに保存したのでflg_down=0 でもよい
    flg_down = 0

def init():
    glClearColor(1.0, 1.0, 1.0, 1.0)
    #色の指定

def main():
    glutInitWindowPosition(100,100)
    glutInitWindowSize(320,240)
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA)
    glutCreateWindow("aka")
    glutDisplayFunc(display)
    glutReshapeFunc(resize)
    glutMouseFunc(mouse)
    glutMotionFunc(motion)
    init()
    #glClearColor() は, プログラムの実行中に背景色を変更する
    #ことがなければ, 最初に一度だけ設定すれば十分です. そこ
    #でこのような初期化処理を行う関数は, glMainLoop() の前に
    #実行する関数 init() にまとめて置くことにします
    glutMainLoop()

if __name__ == "__main__":
    main()
                                                         

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ブログ アーカイブ

ページ

Featured Posts