OpenGLを使った2次元ペイントソフトの開発方法とは?

このQ&Aのポイント
  • BorlandC++Builder4を使って、OpenGLを使った2次元ペイントソフトの開発を目指しています。
  • プログラムの機能はマウスを使った描画、消しゴムのような消去機能、指定範囲の切り取り&移動機能です。
  • 具体的なプログラムの骨子は、OpenGLPanelとTimerをForm上に配置し、マウスイベントで描画や消去を行います。
回答を見る
  • ベストアンサー

OpenGLを使ったプログラムについて

BorlandC++Builder4を使っています。 OpenGLを使って3次元グラフィックを扱うソフトの開発を目標にしており、勉強を始めたばかりなのですが、現在は最終目標の前段階として、OpenGLを使って2次元のペイントソフトを作ろうとしています。 【プログラムの機能・概要】 ・マウスを使っての描画 ・消しゴムのような消去機能 ・指定範囲内の描線の切り取り&移動機能 他にも色の取得や選択など機能を追加していく予定ではありますが、とりあえず上の3つの基本機能を作ろうとしています。切り取り&移動は消去機能が完成した後かな、という感じです。 【プログラムの骨子】 ・OpenGLPanelとTimerをForm上に配置 ・OnMouseDownイベント時に、左クリックで描画開始、右クリックでクリックした座標の指定した範囲の周囲にある描線を消去開始 ・OnMouseMoveイベント時に、左クリックしている間は描線表示、右クリックでクリックしている間は周囲の描線を消去 ・OnMouseUpイベント時に、左クリックUpで描画終了、右クリックUpで消去終了 ・Timerで、描画中のマウス座標を指定時間ごとに記録 考えたのはこんな感じなんですが、これでペイントソフトとして機能させることは可能でしょうか?足りない部分があれば指摘をお願いします。 【わからないこと】 ・座標の記録方法(どのような関数を用いてどんな風に記述すればよいか) ・OnMouseDown、OnMouseMoveの各イベントで、保存した座標を呼び出す方法 glVertex*()を使うことになると思うんですが、具体的にどのように記述すればいいのかわかりません。 ちょっと混乱していて質問自体におかしいところが多いかもしれませんが、どんなことでも構わないのでアドバイス宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmb01
  • ベストアンサー率45% (63/138)
回答No.2

OpenGLでは特に設定をしない限り、 画面の右向きが+x方向、上向きが+y方向、奥向きが-z方向で、 それぞれ-1.0から1.0までの範囲が「見える」範囲になります。 ところがMouseMoveで渡されるX,Yは、例えばウィンドウサイズが640*480だと、 ウィンドウ内ではXが0から640なので、OpenGLの範囲にはまず入りません。 簡単なのはX,Yを-1.0から1.0に修正して使う方法で、 double x=(double)(X-center_x)/width; double y=(double)(center_y-Y)/width; としてglVertex*に渡す。 しかし、OpenGLでの「見える」範囲を変更するのは必ず必要になるので glOrtho, glPerspective, gluLookAt, glViewport 等についてはよく知っておく必要があるでしょう。 マウス移動時に線を引き続けることについては ダブルバッファをオフにして毎回、前回の位置から今回の位置まで線を引くか、 点の位置を全部覚えて、再描画のたびに全部描くかだと思います。 点を書くにはglBegin(GL_POINTS), glPointSize()があります。

kunimi923
質問者

補足

大変参考になりました。 実はOpenGLの様々な参考文献を見ていくと、サンプルプログラムなどで必ず線分の範囲が-1.0~1.0の範囲内でしたので、なぜそれ以上の値がないのだろうと考えていました。glVertex()を使ってただ四角形を表示するような簡単なプログラムを作っても、見えるようにするためにZ軸の座標を色々試してみないと表示されていることを確認できなかったのはこれが原因ですね。glPerspectiveで指定したらきちんと表示されるようになりました。 マウス移動時の線描画に関しても、指摘していただいた方法を試してみようと思います。 また分からないことがあれば聞かせていただきたいと思います。ありがとうございました。

その他の回答 (1)

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.1

3次元グラフィックを扱うソフトとペイントソフトはかなり毛色が違うと思います。 3次元だと線分や面を扱い、ペイントは点を扱うという感じですから。 二次元扱う場合でもCAD、ドロー系の線を扱うソフトの方が近いでしょう。 あと、OpenGLではペイントソフトは向きません。 基本的に線と面を扱うためのものなので、点を扱うのは不適切です。そもそも点を書く関数がなかったと思いますが。 わからないことですが、あまりに漠然としてて答え難いですね。どうにでもできるとか、いろいろあるとしか言えません。 もう少し自分が書きたいプログラムの内容を具体的に考えてみてください。

kunimi923
質問者

補足

現在すでに3次元に線を描くソフトが先輩方によって開発済でして、これに色々な機能を付け加えたり、場合によってはプログラム自体を書き直すための準備段階なんです。 ペイントソフトという言い方が悪かったのかもしれませんが、なんにせよ、もう少し勉強する必要がありそうですね。 ご指摘ありがとうございました。

関連するQ&A

  • Delphi6 OnMouseUp

    deiphi6です。 OnMouseDown,OnMouseMoveイベントで返ってくるX,Y座標値と、OnMouseUpで返ってくるX,Y座標値に違いがあります。 例えば、 ScrollBoxの中にPaintBoxを置いて、PaintBoxのWidth(Height)を32768以上にします。 実行させ、スクロールさせてPaintBoxが32768以上のポイントでマウスボタンを押して離すと。 OnMouseUpで返ってくるX(Y)座標はマイナスになります。 また、65536以上にするとまた1から始まるプラスのX座標がかえってきます。 OnMouseDown,OnMouseMoveでは正常なプラス値です。 つまり、Intergerで返ってきてないってことですか? OnMouseMoveでの座標を代用して使ってますが、マウスの早い動きには正確を欠きます。 何かいい回避方法はありませんでしょうか?

  • C++, MFCにてゲームプログラミング

    C++, MFCにてOpenGLライブラリを使用してぷよぷよを作成しようと考えています。 ぷよの自動落下なのですが、現在仮に「1秒に1マス落下」としています。 しかし、マウスを動かさないと落下してくれません。 ぷよの座標は1秒ごとに1マスずつ変化しています。 (ViewクラスのOnMouseMoveを呼び出さないと描画しない?) ぷよぷよに限った話ではないのですが、原因を教えていただけると嬉しいです・・・ 初歩的な質問ですみません・・・

  • 詳しい方教えて下さい。画像切り取りソフトウェアを探しています。

    お世話になります。 下記、方法で画像切り取り出来るソフトを探しています。 フリーソフトを知っている方がいたら、 教えて下さい。 (1) 切り取りたいpixel数を予め指定 (2) 画像内のある点をクリック (3) クリックした箇所を中心として(1)で設定したpixel数分だけ  切り取られるもしくは選択出来る 現在、irfan viewを使って画像切り取りしているのですが、 切り取り箇所の左上の座標指定が必要です。 なので、今は、    画像内で中心にしたい箇所の座標を確認  → その座標から、指定pixel数を考慮して    切り抜きたい座標の左上座標を計算  → 座標入力にて切り抜き という作業をやっており、わざわざ計算や座標入力しなければ なりません。 上記のような機能があるフリーソフトがあれば、業務が楽になって 助かるのですが、どなたかご教授頂けないでしょうか?

  • プログラミングのopenglで困っています.

    OpenGlの超初心者です. openglで,円を一つ作ってあるsampleプログラムを拾ってきたのですが, 円をもう一つ,別の座標で作りたいのですが,以下のプログラムをどのように編集すればいいですか? 誰か助けてください. ========================================== #include <GLUT/glut.h> #include "glut.h" #include <math.h> //--初期化処理------------------------------------------------------------------ void myinit(void){ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//背景色の設定(R,G,B,ALPHA) 0.0-1.0の範囲で } //--描画内容-------------------------------------------------------------------- void display(void){ float x1,y1,x2,y2; float th1,th2; float th1_rad, th2_rad; float hankei = 0.1; glClear(GL_COLOR_BUFFER_BIT);//画面全体を背景色で塗りつぶす glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //単位行列を行列スタックに読み込む glColor3f(0.0f, 0.0f, 0.0f);//頂点カラーの指定( R, G, B すべてが1.0fなら白) for (th1 = 0.0; th1 <= 360.0; th1 = th1 + 10.0){ th2 = th1 + 10.0; th1_rad = th1 / 180.0 * 3.1415926; // 「度」を「ラジアン」に直す th2_rad = th2 / 180.0 * 3.1415926; x1 = hankei * cos(th1_rad); y1 = hankei * sin(th1_rad); x2 = hankei * cos(th2_rad); y2 = hankei * sin(th2_rad); glBegin(GL_LINES);//glBegin(GL_LINES)とglEnd()の間に glVertex2f( x1, y1 ); //描画したい直線の頂点を並べる glVertex2f( x2, y2 ); glEnd(); //ここまでで,ひとつのオブジェクトの宣言がおわる } glFlush();//OpenGLで実際に描画を行う } //--再描画---------------------------------------------------------------------- void myReshape(GLsizei w, GLsizei h){ glViewport(0,0,w,h); //ウィンドウ全体をビューポートにする glMatrixMode(GL_PROJECTION); glLoadIdentity();//単位行列を行列スタックに読み込む glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); } //--メイン関数------------------------------------------------------------------ int main(int argc, char **argv){ glutInitWindowPosition(100, 100); //(図形が描画される)ウィンドウ位置の設定 glutInitWindowSize(600, 600); //(図形が描画される)ウィンドウサイズの設定 glutInit(&argc, argv);//環境の初期化 glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE); //表示モードの設定 glutCreateWindow("kadai"); //ウィンドウを開く glutDisplayFunc(display); //図形表示関数の指定 myinit(); glutReshapeFunc(myReshape); //座標軸・ビューポート設定関数の指定 glutMainLoop();//無限ループ return 0; } ==========================================

  • ページが完全に読み込まれてから関数を動かす

    <body onMousemove="xxx()"> のようにすると、ページが完全に読み込まれる前に関数が実行されて、 エラーになってしまいます。 関数の中には event.clientX でマウスの位置を取得しているので onMousemoveははずせない??と思います (初心者で、正しく使えてるかわからないのです...) また、エラーが出る原因は、関数の中で指定してるフォームが まだ読み込まれてないこと です ですので、ページが完全に読み込まれれば、エラーはなくなります。 こんな状態です ・event.clientXは、onMousemove や onLoad などがおきたときのマウスのX座標を取得するものですが、マウスの座標を取得する方法はほかにありますか? ・エラーが出ないようにするには何か方法はありますか? エラーが出るのはページが読み込まれるまでの間なので、エラー表示しないような処理をすることになるんですか?

  • opengl

    C++,openGLの質問です. 画像の上で2点を指定し,その2点を用いて画像上に四角形を表示したいのですがどういったpログラムを書けばいいでしょうか?イメージは図のような感じです.(1)と(2)が画像上で指定した点で高さが255の長方形になるようにしたいです. http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#5 のサイトを参考に作ってみたのですが,いまいちわかりません. 以下,自分で作ってみたところです. わかりにくいと思いますが,アドバイスいただけたら嬉しいです. painted_pointはint型のベクターでクリックされた点の位置を保存しています. 最終的には,3点以上の折れ線上に長方形がつながってくっつくのことを予定しています. for(int i = 0; i<painted_point.size(); i++){ GLdouble vertex[][3] = { { painted_point.at(i).x, painted_point.at(i)., 0 }, { painted_point.at(i).x, painted_point.at(i)., 255 } } }; int edge[][2] = { {1 , 2} for(int i=0; i<painted_point.size(); i++){ edge[][2] ={{ i*2 , i*2 + 2}, { i*2+1 , i*2 + 3}, } {painted_point.size()-1,painted_point.size()} }; /* 図形の描画 */ glColor3d(0.0, 0.0, 0.0); glBegin(GL_LINES); for (i = 0; i < 12; ++i) { glVertex3dv(vertex[edge[i][0]]); glVertex3dv(vertex[edge[i][1]]); } glEnd(); }

  • 「プログラムから開く」が出てきません

    まずはOKweve初投稿なのでいたらないところがありましたら申し訳ございません。 私は Windows XP Professional Version 2002 Service Pack 2 を使っているのですが、ファイルを右クリックしても「プログラムから開く」や、「アプリケーションから開く」という文章が出てこずに困っています。 一度左クリックでファイルを指定しそれから「Shiftキー」を押しながら右クリックを押しても駄目でした。 右クリックをしてから「プログラムを開く」コマンドを表示するやり方を教えて下さい。 お願いします。

  • XPに付属している「ペイントソフト」を利用して切り取りをしています。

    XPに付属している「ペイントソフト」を利用して切り取りをしています。 手順はこのとおりです。 しかし5で貼り付けると、画像の下に白紙部分がはみ出るのですが この処理方法が分りません。 初心者なのでよろしくお願いいたします。 1.選択アイコンをクリックし、範囲を指定する 2.<編集(E)>または右クリックで<切り取り>を選択 3.<ファイル(F)>クリックし、<新規>選択 4.<○○への変更を保存しますか>はいいえを選択 5.<編集(E)>または右クリックし、<貼り付け>選択 6.<ファイル(F)><名前を付けて保存>

  • MouseDownとMouseMoveイベントで質問です。

    学校の課題の為VB6.0でマウスを使用したプログラムを作成しているのですが、 MouseDownイベントとMouseMoveイベントで解らないことがあるので、 知っているかた、お願いします。 マウスの右ボタンと左ボタンの区別をつけるにはどうしたらいいのでしょうか? 例えば「左の時は描画し、右の時は描画しない」と言う感じで… わからなくて困っています。ぜひ、お願いします。

  • Javaで左上の位置を指定して文字を描画する方法を探しています。

    Javaで左上の位置を指定して文字を描画する方法を探しています。 JavaでGraphicsオブジェクトを使用して文字を描画する際に、Javaの標準の方法(java.awt.graphicsのdrawStringメソッド)を使う場合では「ベースラインの位置」を指定しますが、これを「左上端の座標」を指定して描画できるようにするにはどうしたらよいのでしょうか。

    • ベストアンサー
    • Java