質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Q&A

解決済

1回答

6727閲覧

OpenGLでマウスで描画できるようにしたい。

0126tami

総合スコア60

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

0グッド

0クリップ

投稿2018/05/31 16:14

編集2018/05/31 16:28

OpenGL(2015)をつかって簡単なお絵かきソフトのようなものを作りたいと思っています。

そしてプログラムを途中まで作ることができました
今の時点で、マウスでクリックしていくとクリックしたところから次にクリックしたところまで直線がかけるというプログラムになっています。

それをマウスでクリックし続けているときに線が書けるようにしたいのです。
いわゆる普通のペイントみたいな感じです。

マウスでクリックしているときからマウスの手をはなすまでの間にディスプレイ上に描画するような関数?を作ればいいのかなとは思うのですが
OpenGL初心者なものでまったくわかりません。

だからわかる方ぜひ教えてください。

#include "stdafx.h" #include <stdlib.h> #include <gl/glut.h> int WINW = 600; int WINH = 400; const int TEXTMAX = 40; const int POINTMAX = 10; char text[TEXTMAX]; double xList[POINTMAX]; double yList[POINTMAX]; int textnum; int pointnum; void DrawString() { glRasterPos3d(0, 0, 0);//0,0,0位置をスタート位置にする glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'P'); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'a'); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'i'); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'n'); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 't'); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'!'); } void myDisplay() { int i, j; glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); DrawString(); glColor3d(1.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); for (i = 0; i < POINTMAX; i++) { j = (pointnum + i) % POINTMAX; if (xList[j] >= -1.0 && yList[j] >= -1.0) { glVertex2d(xList[j], yList[j]); } } glEnd(); glRasterPos2d(-0.9, -0.7); glutSwapBuffers(); } void myKeyboard(unsigned char key, int x, int y) { if (key == 0x1B) exit(0); text[textnum] = key; textnum = (textnum + 1) % TEXTMAX; glutPostRedisplay(); } void myMouseFunc(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { xList[pointnum] = (((double) x/ WINW) * 2) - 1; yList[pointnum] = ((((double)y / WINH) * 2) - 1)*(-1); pointnum = (pointnum + 1) % POINTMAX; glutPostRedisplay(); } } void myReshape(int width, int height) { glViewport(0, 0, width, height); WINW = width; WINH = height; } void myInit(char* progname) { int i; glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(WINW, WINH); glutInitWindowPosition(0, 0); glutCreateWindow(progname); pointnum = 0; for (i = 0; i < POINTMAX; i++) { xList[i] = -10.0; yList[i] = -10.0; } textnum = 0; for (i = 0; i < TEXTMAX; i++) { text[i] = '?0'; } } int main(int argc, char* argv[]) { glutInit(&argc, argv); myInit(argv[0]); glutKeyboardFunc(myKeyboard); glutMouseFunc(myMouseFunc); glutReshapeFunc(myReshape); glutDisplayFunc(myDisplay); glutMainLoop(); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

現状のコードではマウスボタン押下のたびに折れ線の頂点を追加していますが、代わりにドラッグイベント(GLUTだと「モーション」というらしいですね...初めて知りました)で同じことをしてみるのはどうでしょう?
細かい折れ線で曲線を表現するイメージです。どちらかというとペイント系ソフトよりもドロー系ソフトのようなアプローチですが...

C++

1#include "stdafx.h" 2#include <stdlib.h> 3#include <gl/glut.h> 4 5int WINW = 600; 6int WINH = 400; 7const int TEXTMAX = 40; 8const int POINTMAX = 10000; // 大量の角を持つ折れ線を描いているのだから、バッファサイズが10点分しかないと線がすぐ消えていってしまう 9char text[TEXTMAX]; 10double xList[POINTMAX]; 11double yList[POINTMAX]; 12int textnum; 13int pointnum; 14 15void DrawString() { 16 glRasterPos3d(0, 0, 0);//0,0,0位置をスタート位置にする 17 18 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'P'); 19 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'a'); 20 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'i'); 21 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'n'); 22 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 't'); 23 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, '!'); 24} 25 26void myDisplay() { 27 int i, j; 28 29 glClearColor(1.0, 1.0, 1.0, 0.0); 30 glClear(GL_COLOR_BUFFER_BIT); 31 32 DrawString(); 33 34 glColor3d(1.0, 0.0, 0.0); 35 glBegin(GL_LINE_STRIP); 36 for (i = 0; i < POINTMAX; i++) { 37 j = (pointnum + i) % POINTMAX; 38 if (xList[j] == -20.0) { 39 // 座標バッファに目印となる値が見つかったら、そこをラインストリップの区切りとする 40 glEnd(); 41 glBegin(GL_LINE_STRIP); 42 } else if (xList[j] >= -1.0 && yList[j] >= -1.0) { 43 glVertex2d(xList[j], yList[j]); 44 } 45 } 46 glEnd(); 47 48 glRasterPos2d(-0.9, -0.7); 49 50 glutSwapBuffers(); 51} 52 53 54void myKeyboard(unsigned char key, int x, int y) { 55 if (key == 0x1B) exit(0); 56 text[textnum] = key; 57 textnum = (textnum + 1) % TEXTMAX; 58 glutPostRedisplay(); 59} 60 61void myMouseFunc(int button, int state, int x, int y) { 62 if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { 63 // マウスボタンが放されたら、目印となる適当な値を座標バッファに入れてやる 64 // myDisplay中でその値が見つかったら、そこでラインストリップを区切ってやる 65 xList[pointnum] = -20.0; 66 yList[pointnum] = 0.0; 67 pointnum = (pointnum + 1) % POINTMAX; 68 glutPostRedisplay(); 69 } 70} 71 72void myMotionFunc(int x, int y) { 73 // 前回のマウス座標と相違があれば、変更前のmyMouseFuncの 74 // ifブロック内でやっていたのと同じことを行う 75 static int prevX = -10.0, prevY = -10.0; 76 if (x == prevX && y == prevY) return; 77 prevX = x; 78 prevY = y; 79 xList[pointnum] = (((double)x / WINW) * 2) - 1; 80 yList[pointnum] = ((((double)y / WINH) * 2) - 1)*(-1); 81 pointnum = (pointnum + 1) % POINTMAX; 82 glutPostRedisplay(); 83} 84 85void myReshape(int width, int height) { 86 glViewport(0, 0, width, height); 87 WINW = width; 88 WINH = height; 89} 90 91void myInit(char* progname) { 92 int i; 93 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 94 glutInitWindowSize(WINW, WINH); 95 glutInitWindowPosition(0, 0); 96 glutCreateWindow(progname); 97 pointnum = 0; 98 for (i = 0; i < POINTMAX; i++) { 99 xList[i] = -10.0; 100 yList[i] = -10.0; 101 } 102 textnum = 0; 103 for (i = 0; i < TEXTMAX; i++) { 104 text[i] = '?0'; 105 } 106} 107 108int main(int argc, char* argv[]) { 109 glutInit(&argc, argv); 110 myInit(argv[0]); 111 glutKeyboardFunc(myKeyboard); 112 glutMouseFunc(myMouseFunc); 113 glutMotionFunc(myMotionFunc); // モーションイベント用のハンドラーを登録 114 glutReshapeFunc(myReshape); 115 glutDisplayFunc(myDisplay); 116 glutMainLoop(); 117 return 0; 118}

(参考:WisdomSoft(旧) - OpenGL入門 - GLUT のイベント

投稿2018/05/31 20:10

編集2018/05/31 22:05
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0126tami

2018/06/01 03:41

とっても助かりますありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問