Experimento 3—Dibujo interactivo con teclado OpenGL

1. Propósito del experimento

1. Comprenda el concepto del sistema de coordenadas OpenGL, domine el concepto de la ventana de recorte OpenGL, la ventana gráfica, la ventana de visualización y la relación entre ellos, y aprenda a calcular las coordenadas mundiales y las coordenadas de la pantalla.
2. Aprenda la operación interactiva del teclado simple de OpenGL.
3. Aprende el dibujo de personajes simple de OpenGL.
4. Domine aún más el dibujo de puntos, líneas y polígonos de OpenGL.

2. Contenido experimental

1. Llame el código fuente del Experimento 1 para ejecutar, ajustar y modificar la ventana de visualización para mantener el tamaño predeterminado (300x300) en el centro de la pantalla, y dibuje un rectángulo en el centro de la ventana de visualización, como se muestra en la figura a continuación: Consejos: 1) Agregue la función glutInitWindowPosition para modificar la posición
inserte la descripción de la imagen aquí
de la ventana
(int x, int y), donde (x, y) es la posición en la pantalla de la esquina superior izquierda de la ventana.
2) Las coordenadas de la esquina inferior izquierda de la ventana de visualización son (-1,-1), y las coordenadas de la esquina superior derecha son (1,1).
2. Agregue la interacción del teclado sobre la base del Experimento 1, presione la tecla W para mover el rectángulo dibujado hacia arriba, presione la tecla S para mover el rectángulo hacia abajo, presione la tecla A para mover el rectángulo hacia la izquierda y presione la tecla D para mover el rectángulo a la derecha, como se muestra en la Figura Experimental 3-2. Los pasos de referencia son los siguientes:
1) Agregar una función de devolución de llamada de registro de teclado en la función principal:
glutKeyboardFunc(mykeyboard);
Esta función se puede colocar después de glutDisplayFunc(display).
2) Modifique el código de dibujo del rectángulo en la función de dibujo de pantalla (), y reemplace los parámetros numéricos con variables.
Por ejemplo:
glRectf(-0.5,-0.5,0.5,0.5);
Cambiar a:
agregar declaración de variable y valor inicial antes del programa, como:
float xl=-0.5,yl=-0.5,x2=0.5,y2=0.5 ;
Tenga en cuenta la posición de la instrucción.
3) Agregue la subfunción de teclado mykeyboard en el programa y modifíquela en el siguiente código para realizar el movimiento del teclado para controlar el rectángulo y ejecute el programa para probarse a sí mismo.

void mykeyboard(unsigned char key, int x, int y) {
    
    
    switch (key) {
    
    
    case 'W':
    case 'w':    //矩形对角坐标变量修改使得矩形上移 
        y1 += 0.1; y2+=0.1;
        break;
    case 'S':
    case 's':   //矩形对角坐标变量修改使得矩形下移 
        y1-=0.1;y2-=0.1;
        break;
    case 'A':
    case 'a':    //矩形对角坐标变量修改使得矩形左移
        x1-=0.1; x2-=0.1;
        break;
    case 'D':
    case 'd':	//矩形对角坐标变量修改使得矩形右移 
        x1+=0.1; x2+=0.1;
        break;
    }
    //参数修改后调用重画函数,屏幕图形将发生改变 
    glutPostRedisplay();
}

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
3. Configure la función de devolución de llamada de cambio de ventana para que la longitud y el ancho del rectángulo sean iguales a 100. Cuando se inicia el programa, el rectángulo todavía está en el centro de la ventana. Cuando la ventana de visualización está maximizada, el rectángulo dibujado también aumenta , como se muestra en la Figura 3-3.
1) Agregue una función de cambio de ventana registrada en la función principal:
glutReshapeFunc (myreshape); // antes de glutMainLoop ()
2) Agregue una subfunción de cambio de ventana en el programa, los parámetros W y h son el ancho y alto de la actual ventana de visualización:

void myreshape(GLsizei w, GLsizei h) {
    
    
    glViewport(0, 0, w, h);             //设置视区位置
    glMatrixMode(GL_PROJECTION);        //设置投影变换模式
    glLoadIdentity();                   //调整单位矩阵,清空当前矩阵堆栈
    gluOrtho2D(0, 300, 0, 300);         
}

3) En este punto, la variable inicial del rectángulo se recalcula como:
float x1= 100, x1=100, x2=200, y2=200;
Nota: se pide a los lectores que piensen por qué la variable inicial del rectángulo se cambia del original (-0.5,- 0.5, 0.5, 0.5) se convierte en (100, 100, 200, 200) ¿Cuáles son
las reglas para configurar la función de configuración de la ventana de recorte gluOrtho2D (xwmin, xwmax, ywmin, ywmax) y el función de configuración de ventana gráfica glView-port (startx, starty, viewport_width, viewport_height)?
Respuesta: Es causado por la función glOrtho. El propósito de esta función es establecer o recortar la extensión del espacio. La sintaxis es: void glOrtho(GLdoble a la izquierda, GLdoble a la derecha, GLdoble fondo, GLdoble arriba, GLdoble cerca, GLdoblelejos); izquierda significa la coordenada más a la izquierda, derecha significa la coordenada más a la derecha, abajo significa la coordenada más abajo, arriba significa las coordenadas más arriba, cerca significa las coordenadas del borde frontal y far significa las coordenadas del último borde.

En este punto, presione las teclas W, A, D y S del teclado para moverse de forma interactiva.¿Cómo cambia la distancia de movimiento del rectángulo en comparación con antes? ¿Cómo debe modificarse el programa para mantener la frecuencia de movimiento anterior?
R: Hazte más pequeño y apenas te muevas. Modifica la variable de coordenadas diagonales del rectángulo.
Antes de cambiar la ventana de visualización:
inserte la descripción de la imagen aquí
Después de cambiar la ventana de visualización:
inserte la descripción de la imagen aquí
4. Agregue el carácter "Hola" en el medio del rectángulo y observe el resultado, luego cambie el carácter "Hola" al pinyin o nombre en inglés de su propio nombre . Como se muestra abajo.
Sugerencia: agregue el siguiente código después de dibujar el rectángulo.

glColor3f(1,0,0);
glRasterPos2i((x1+x2)/2,(y1+y2)/2); 				//定位当前光标
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘H’);	//写字符"H"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘e’);	//写字符"e"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘l’);	//写字符"l"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘l’);	//写字符"l"
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘o’);	//写字符"o"

inserte la descripción de la imagen aquí
Nota: Ejecute el programa, el efecto es como se muestra en la figura de arriba. Pero si presiona las teclas W, A, D y S en el teclado para moverse de forma interactiva, ¿qué pasará con el programa? ¿Cómo debe modificarse el programa para mantener el rectángulo blanco y los caracteres rojos?
A: El texto se mueve con los caracteres. Rectángulos y texto definen diferentes colores
Si la declaración de configuración de color de carácter glColor3f(1,0,0) se coloca después de la declaración de posicionamiento del cursor glRasterPos2i((xl1+x2)/2,(y1+y2)/2), ¿qué sucederá cuando ejecuta variedad? Se pide a los lectores que resuman el orden de la declaración de color de los caracteres por sí mismos.
R: Los caracteres están bloqueados y solo hay un rectángulo. La configuración del color del carácter debe estar antes de la declaración del cursor de posicionamiento.

5. Consulte el libro de texto y dibuje una figura plana bidimensional de acuerdo con sus propias ideas, reemplace el rectángulo anterior con la figura plana bidimensional que concibió para realizar la función interactiva, preste atención al orden de los vértices y marque su nombre en la pantalla.
código:

#include "stdafx.h"
#include "Shiyan3.h"
#include <windows.h>
#include <gl/glut.h>
float x1=100,y1=100,x2=200,y2=200;
void display(void)
{
    
    
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    //设置清屏颜色 
    glClear(GL_COLOR_BUFFER_BIT);           //刷新颜色缓存区
    glRectf(x1, y1, x2, y2);        //矩形
    glColor3f(1.0f, 1.0f, 1.0f); 
	glColor3f(1,0,0);
	glRasterPos2i((x1+x2)/2,(y1+y2)/2); 				//定位当前光标
	glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'X');	//写字符"X"
	glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'X');	//写字符"X"
	glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'X');	//写字符"X"
    glFlush();                              //用于刷新命令队列和缓存区,使所有尚未被执行的OpenGL命令得到执行

}
void mykeyboard(unsigned char key, int x, int y) {
    
    
    switch (key) {
    
    
	case 'W':
    case 'w':    //矩形对角坐标变量修改使得矩形上移 
        y1+= 0.1; y2+=0.1;
        break;
    case 'S':
    case 's':   //矩形对角坐标变量修改使得矩形下移 
        y1-=0.1;y2-=0.1;
        break;
    case 'A':
    case 'a':    //矩形对角坐标变量修改使得矩形左移
        x1-=0.1; x2-=0.1;
        break;
    case 'D':
    case 'd':	//矩形对角坐标变量修改使得矩形右移 
        x1+=0.1; x2+=0.1;
        break;
    }
    //参数修改后调用重画函数,屏幕图形将发生改变 
    glutPostRedisplay();
}
void myreshape(GLsizei w, GLsizei h) {
    
    
    glViewport(0, 0, w, h);             //设置视区位置
    glMatrixMode(GL_PROJECTION);        //设置投影变换模式
    glLoadIdentity();                   //调整单位矩阵,清空当前矩阵堆栈
    gluOrtho2D(0, 300, 0, 300);         
}
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR  lpCmdLine,int   nCmdShow)
{
    
    
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	char *argv[] = {
    
     "hello"," " };
	int argc = 2;
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(300,300);
	int cx = glutGet(GLUT_SCREEN_WIDTH);  
    int cy = glutGet(GLUT_SCREEN_HEIGHT);  
    glutInitWindowPosition((cx-500)/2,(cy-500)/2);  
	glutCreateWindow("hello");
	glutDisplayFunc(display);
	glutKeyboardFunc(mykeyboard);
	glutReshapeFunc (myreshape);
	glutMainLoop();
	return 0;
}

Resultados experimentales:
inserte la descripción de la imagen aquí

3. Preguntas para pensar

Siga estos pasos y analice la relación entre la ventana de recorte, la ventana gráfica y la ventana de visualización.
1) Modifique el tamaño de la ventana gráfica a la mitad del tamaño original, como se muestra en la figura.
2) Modifique el tamaño de la ventana de recorte a la mitad del tamaño original; la ventana gráfica permanece sin cambios, como se muestra en la figura.
Función de referencia:
・Función de configuración de la ventana de recorte:
gluOrtho2D (xwmin, xwmax, ywmin, ywmax); //xwmin xwmax, ywmin, ywmax son las posiciones de la ventana de recorte en el sistema de coordenadas mundiales, respectivamente x mínimo, x máximo, y mínimo , y Máxima
• función de configuración de la ventana gráfica:
glViewport (startx, starty, viewport_width, viewport_height) ;//La posición del área de dibujo en la ventana de visualización, tomando el sistema de coordenadas de la pantalla como referencia, startx, starty.viewport_widthviewport_height son los puntos de inicio del área de dibujo en la ventana de visualización Posición, así como el ancho y alto del área de dibujo
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
3) Modifique el programa anterior para que presione la tecla número 1 para realizar el rectángulo, use las teclas W, S, A, D para controla el movimiento arriba, abajo, izquierda y derecha, y presiona la tecla 2 para mostrar otros gráficos 2D concebidos por ti mismo (triángulo, punto o polígono, etc.), usa las teclas W, S, A, D para controlar arriba, abajo, movimiento de derecha e izquierda.
Modificación de código:

void mykeyboard(unsigned char key, int x, int y) {
    
    
    switch (key) {
    
    
    case 'W':
    case 'w':    //矩形对角坐标变量修改使得矩形上移 
        y1 += 1; y2 += 1;
        break;
    case 'S':
    case 's':   //矩形对角坐标变量修改使得矩形下移 
        y1 -= 1;y2 -= 1;
        break;
    case 'A':
    case 'a':    //矩形对角坐标变量修改使得矩形左移
        x1 -= 1; x2 -= 1;
        break;
    case 'D':
    case 'd':	//矩形对角坐标变量修改使得矩形右移 
        x1 += 1; x2 += 1;
        break;
    case '1':   //显示窗口改变
        w1 = 300; h1 = 300;
        break;
    case '2':	//显示窗口改变
        w1 = 150; h1 = 150;
        break;
    }
    //参数修改后调用重画函数,屏幕图形将发生改变 
    glutPostRedisplay();
}

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_52030647/article/details/130726696
Recomendado
Clasificación