Expérience 4—Dessin interactif avec une souris OpenGL

1. But de l'expérience

1. Maîtrisez la fonction de réponse au bouton de la souris d'OpenGL.
2. Maîtrisez la fonction de réponse au mouvement de la souris d'OpenGL.
3. Consolidez davantage la base de base du dessin primitif d'OpenGL

2. Contenu expérimental

1. Dessinez un croquis avec la souris - réalisez que partout où la souris est cliquée, la ligne sera tracée.
Idées :
1) Enregistrez les sous-fonctions de réponse et de mouvement de la souris dans le programme principal :

glutMouseFunc(mymouse);
glutMotionFunc(mymotion)

Placez-le après l'enregistrement de l'affichage et avant la boucle principale.
2) Déclarez les sous-fonctions de réponse et de mouvement de la souris dans l'en-tête du programme :

void myMouse(int button,int state,int x,int y); 
void myMotion(int x,int y);

3) Construisez la sous-fonction de réponse de la souris :
//événement de réponse du bouton de la souris

void myMouse(int button, int state,int x,int y)
{
    
    
//鼠标左键按下——确定起始点
//鼠标左键松开——画最后一个顶点,画线结束
}

4) Construisez la sous-fonction de mouvement de la souris :
// Obtenez les coordonnées du mouvement de la souris lorsque la souris se déplace

void myMotion(int x,int y)
{
    
    
/ /鼠标移动	线画到哪
}

5) Modifier la fonction d'affichage Display() :

#include "stdafx.h"
#include "Shiyan4.h"
#include <windows.h>
#include <gl/glut.h>
//画直线程序框架
int ww, hh;	//显示窗口宽和高
void Myinit(void);
void Reshape(int w, int h);
void Display(void);
int APIENTRY _tWinMain(HINSTANCE hlnstance, HINSTANCE hPrevInstance, LPTSTR	IpCmdLine,int	nCmdShow)
{
    
    
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(IpCmdLine);
char *argv[] = {
    
    "hello"," "}; 
int argc = 2; // argv中的字符串数	
glutInit(&argc, argv);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("H鼠标画线小程序演示");
Myinit ();	//初始化GLUT库
//设置显示窗口大小
//设置显示模式(注意双缓存)
//创建显示窗口
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);	//注册显示回调函数
//注册窗口改变回调函数	
glutMainLoop(); 
return 0;	//进入事件处理循环	
}
void Myinit(void)
{
    
    
	glClearColor(0.0,0.0,0.0,0.0);
	glLineWidth(3.0);
}
//渲染绘制子程序
void Display(void)
{
    
    
glClear (GL_COLOR_BUFFER_BIT) ; // 刷新颜色缓存区 glBegin(GL_LINES);
glVertex2f(0, 0);
glVertex2f(ww,hh);
glEnd();
glutSwapBuffers ();	//双缓存的刷新模式
}
void Reshape(int w, int h){
    
    
	glMatrixMode(GL_PROJECTION);	//投影矩阵模式
	glLoadIdentity();	//矩阵堆栈清空
	glViewport(0, 0, w, h);	//设置视区大小
	gluOrtho2D(0, w, 0, h);	//设置裁剪窗口大小
	ww=w;	
	hh=h;	
}

2. Tracez une ligne avec la souris. Lisez le programme de dessin de ligne de souris OpenGL, vous pouvez utiliser la souris pour dessiner de manière interactive plusieurs lignes droites dans la fenêtre de dessin, appuyez d'abord sur le bouton gauche de la souris pour déterminer le point de départ de la ligne droite, appuyez sur le bouton gauche de la souris et déplacez-vous en même temps temps, voir le processus de dessin de ligne, relâchez le bouton gauche de la souris. Lorsque cette option est activée, déterminez le point final de la ligne droite et dessinez plusieurs lignes droites à plusieurs reprises.
Idées :
1) Écrivez un cadre de programme pour dessiner plusieurs lignes statiques et remplacez les coordonnées par des variables.
2) Enregistrez la fonction de réponse au bouton de la souris et la fonction de réponse au mouvement de la souris dans la fonction principale.
3) Donnez l'événement de réponse au bouton de la souris dans la sous-fonction de réponse au bouton de la souris.
4) Indiquez l'événement de réponse au mouvement de la souris dans la sous-fonction de réponse au mouvement de la souris.
5) Lire et analyser le programme, et conserver le programme.

#include <windows.h>
#include <stdio.h>
#include "stdafx.h"
#include "Shiyan4.h"
#include <gl/glut.h>
#define N 1000				//线段最大条数
int line[N][4], k = 0;		//线段坐标存储数组, 线段计数
int ww, hh;					//显示窗口的宽和高
void myMouse(int button, int state, int x, int y);
void myMotion(int x, int y);
void Myinit(void);
void Reshape(int w, int h);
void display(void);
void drawines();
int APIENTRY wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{
    
    
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
	char* argv[] = {
    
     "hello "," " };
	int argc = 2;		//argv中的字符串数
	int sheight = glutGet(GLUT_SCREEN_WIDTH);
	int swidth = glutGet(GLUT_SCREEN_HEIGHT);
	glutInit(&argc, argv);							//初始化GLUT库
	glutInitWindowSize(800, 600);					//绘图窗口大小
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutCreateWindow("鼠标画线小程序演示");	//创建显示窗口
	Myinit();
	glutDisplayFunc(display);				//注册显示回调函数
	glutMouseFunc(myMouse);					//注册鼠标按钮回调函数
	glutMotionFunc(myMotion);				//注册鼠标移动回调函数
	glutReshapeFunc(Reshape);				//注册窗口改变回调函数
	glutMainLoop();							//表示开始运行程序,用于程序的结尾
	return 0;
}
void Myinit(void) {
    
    
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glLineWidth(3.0);
}
//画线子程序
void drawlines() {
    
    
	for (int i = 0; i <= k; i++) {
    
    
		glBegin(GL_LINES);
		glVertex2f(line[i][0], line[i][1]);
		glVertex2f(line[i][2], line[i][3]);
		glEnd();
	}
}
//渲染绘制子程序
void display(void) {
    
    
	glClear(GL_COLOR_BUFFER_BIT);//刷新颜色缓存区
	drawlines();				//画线子程序
	glutSwapBuffers();			//双缓存的刷新模式
}
void Reshape(int w, int h)		//窗口改变时自动获取显示窗口的宽w和高h
{
    
    
	glMatrixMode(GL_PROJECTION);//投影矩阵模式
	glLoadIdentity();			//矩阵堆栈清空
	glViewport(0, 0, w, h);		//设置视区大小
	gluOrtho2D(0, w, 0, h);		//设置裁剪窗口大小
	ww = w;
	hh = h;
}
//鼠标按钮响应事件
void myMouse(int button, int state, int x, int y)
{
    
    
	//鼠标左键按下——确定起始点
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
    
    
		line[k][0] = x;				//线段起点x坐标
		line[k][1] = hh - y;		//线段终点y坐标
	}
	//鼠标左键松开——画最后一个顶点,画线结束
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
    
    
		line[k][2] = x;				//线段起点x坐标
		line[k][3] = hh - y;		//线段终点y坐标
		k++;
		glutPostRedisplay();
	}
}
//鼠标移动时获得鼠标移动中的坐标
void myMotion(int x, int y)
{
    
    
	//get the line's motion point
	line[k][2] = x;				//动态终点的x坐标
	line[k][3] = hh - y;		//动态终点的y坐标
	glutPostRedisplay();
}

Résultats expérimentaux :
insérez la description de l'image ici
3. La souris dessine un rectangle. Modifier le programme de dessin au trait de la souris. Prérequis : être capable de dessiner interactivement plusieurs rectangles avec la souris dans la fenêtre de dessin. Appuyer d'abord sur le bouton gauche de la souris pour déterminer le point de départ de la diagonale du rectangle. Appuyer sur le bouton gauche de la souris et se déplacer à en même temps pour voir le processus de dessin du rectangle. Relâchez le bouton gauche pour déterminer un autre point sur la diagonale du rectangle, et plusieurs rectangles peuvent être dessinés à plusieurs reprises. comme le montre l'image.
Résultats expérimentaux :
insérez la description de l'image ici
Code :

//鼠标绘制矩形rect_draw.cpp
#include <GL/glut.h>
#include <iostream>
#define N 1000				//矩形最大个数
int k = 0;					//矩形计数
int ww, hh;					//显示窗口的宽和高
//int corner[N][4];
struct GLintPoint {
    
    		//矩形结构
	int x, y;
};
GLintPoint corner[N][2];
/*矩形存储数组,第i个矩形坐标
x0 = corner[i][0].x
y0 = corner[i][0].y
x1 = corner[i][1].x
y1 = corner[i][1].y
*/
void myMouse(int button, int state, int x, int y);
void myMotion(int x, int y);
void myinit(void);
void Reshape(int w, int h);
void display(void);
void drawRects();
INT WINAPI wWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPTSTR	lpCmdline,
	int		nCmdShow)
{
    
    
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdline);
	char *argv[] = {
    
     (char *)"hello ",(char *)" " };
	int argc = 2;
	glutInit(&argc, argv);			//initialize glut  library
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800, 600);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("Mouse draw Rectangle");
	myinit();
	glutDisplayFunc(display);
	glutMouseFunc(myMouse);
	glutMotionFunc(myMotion);
	glutReshapeFunc(Reshape);
	glutMainLoop();
	return 0;
}

void myinit(void) {
    
    
	glClearColor(0, 0, 0, 0);
	glLineWidth(3.0);
}
//矩阵绘制子程序
void drawRects() {
    
    
	for (int i = 0; i <= k; i++) {
    
    
		glBegin(GL_LINE_LOOP);
		glVertex2f(corner[i][0].x, corner[i][0].y);		//x0,y0
		glVertex2f(corner[i][0].x, corner[i][1].y);		//x0,y1
		glVertex2f(corner[i][1].x, corner[i][1].y);		//x1,y1
		glVertex2f(corner[i][1].x, corner[i][0].y);		//x1,y0	
		glEnd();
	}
}
//display()函数
void display(void) {
    
    
	glClear(GL_COLOR_BUFFER_BIT);
	drawRects();

	glutSwapBuffers();
}
void Reshape(int w, int h)		//窗口改变时自动获取显示窗口的宽w和高h
{
    
    
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);		//设置视区大小
	gluOrtho2D(0, w, 0, h);		//设置裁剪窗口大小
	ww = w;
	hh = h;
}
//鼠标按钮响应事件
void myMouse(int button, int state, int x, int y)
{
    
    
	//鼠标左键按下——确定第一个矩形对角点
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
    
    
		corner[k][0].x = x;		//x1
		corner[k][0].y = hh - y;	//y1
	}
	//鼠标左键松开——画下一个对角点,将矩形个数加1,画线结束
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
    
    
		corner[k][1].x = x;		//x2
		corner[k][1].y = hh - y;	//y2
		k++;
		glutPostRedisplay();
	}
}
void myMotion(int x, int y)
{
    
    
	//get the line's motion point
	corner[k][1].x = x;
	corner[k][1].y = hh - y;
	glutPostRedisplay();
}

4. Question de réflexion : Dessinez un cercle avec la souris. Comment modifier le code lorsque la souris dessine un cercle ?
Résultats expérimentaux :
insérez la description de l'image ici
Code :

#include "stdafx.h"
#include "ShiYan4-2.h"
//鼠标绘制矩形
#define GLUT_DISABLE_ATEXIT_HACK
#include <windows.h>
#include <gl/glut.h>
#include <math.h>
#define N 1000				//圆最大个数
#define PI  3.14159			//设置圆周率 
int n = 3600, R;			//多边形边数,外接圆半径 
float theta = 0.0;			//旋转初始角度值
int k = 0;		//圆数据存储数组,圆计数
int r[N][3];
int ww, hh;					//显示窗口的宽和高
struct GLintPoint {
    
    		//矩形结构
	int x, y;
};
GLintPoint corner[N][2];
void myMouse(int button, int state, int x, int y)
{
    
    
	//鼠标左键按下——确定第一个圆的对角点
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
    
    
		corner[k][0].x = x;			//x1
		corner[k][0].y = hh - y;	//y1
	}
	//鼠标左键松开——画下一个对角点,将圆个数加1,画线结束
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
    
    
		corner[k][1].x = x;		//x2
		corner[k][1].y = hh - y;	//y2
		r[k][0] = (corner[k][0].x + corner[k][1].x) / 2;
		r[k][1] = (corner[k][0].y + corner[k][1].y) / 2;
		r[k][2] = sqrt(double((corner[k][0].x - corner[k][1].x)*(corner[k][0].x - corner[k][1].x) +(corner[k][0].y - corner[k][1].y) *(corner[k][0].y - corner[k][1].y))) / 2;
		k++;
		glutPostRedisplay();
	}
}
void myMotion(int x, int y)
{
    
    
	//get the line's motion point
	corner[k][1].x = x;
	corner[k][1].y = hh - y;
	glutPostRedisplay();
}
void Myinit(void) {
    
    
	glClearColor(0, 0, 0, 0);
	glLineWidth(3.0);
}
void Reshape(int w, int h)		//窗口改变时自动获取显示窗口的宽w和高h
{
    
    
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);		//设置视区大小
	gluOrtho2D(0, w, 0, h);		//设置裁剪窗口大小
	ww = w;
	hh = h;
}
//圆绘制子程序
void drawRound() {
    
    
	for (int i = 0; i <= k; i++) {
    
    
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < n; j++)
			glVertex2f((r[i][0] + r[i][2] * cos(j * 2 * PI / n)), (r[i][1] + r[i][2] * sin(j * 2 * PI / n)));  //顶点坐标 
		glEnd();
	}
}
void display(void) {
    
    
	glClear(GL_COLOR_BUFFER_BIT);
	drawRound();
	glutSwapBuffers();
}
INT WINAPI wWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPTSTR	lpCmdline,
	int		nCmdShow)
{
    
    
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdline);
	char* argv[] = {
    
     (char*)"hello ",(char*)" " };
	int argc = 2;
	glutInit(&argc, argv);			//initialize glut  library
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800, 600);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("鼠标绘制圆形");
	Myinit();
	glutDisplayFunc(display);
	glutMouseFunc(myMouse);
	glutMotionFunc(myMotion);
	glutReshapeFunc(Reshape);
	glutMainLoop();
	return 0;
}
3. Fonctions et codes de référence

Reportez-vous au chapitre 5 du manuel pour les fonctions de base du dessin primitif et au chapitre 6 pour les fonctions d'interaction avec la souris.
1) Fonction de réglage de la fenêtre de découpage :

gluOrtho2D(xwmin,xwmax,ywmin,ywmax);

2) Fonction de réglage de la fenêtre :

glViewport(startx,starty,viewport_width,viewport_height);

3) Exemple de code de dessin de polyligne à la souris :
// Commence à dessiner une polyligne lorsque le bouton de la souris est enfoncé et se termine lorsque le bouton de la souris est relâché

glutMotionFunc(mymotion);
void mymotion(int x,int y)
{
    
    .
if (first_time_called)
glBegin(GL_LINE_STRIP);
glVertex2f (sx* (GLfloat) x, sy* (GLfloat) (h-y));
}
//注意:鼠标按钮松开时产生glEndO

insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_52030647/article/details/130727608
conseillé
Classement