Experiment 3—OpenGL keyboard interactive drawing

1. Purpose of the experiment

1. Understand the concept of OpenGL coordinate system, master the concept of OpenGL clipping window, viewport, display window and the relationship between them, and learn to calculate world coordinates and screen coordinates.
2. Learn the simple keyboard interactive operation of OpenGL.
3. Learn the simple character drawing of OpenGL.
4. Further master the drawing of OpenGL points, lines, and polygons.

2. Experimental content

1. Call up the source code of Experiment 1 to run, adjust and modify the display window to maintain the default size (300x300) in the center of the screen, and draw a rectangle in the center of the display window, as shown in the figure below: Tips: 1) Add the function glutInitWindowPosition to modify the
insert image description here
window
position (int x, int y), where (x, y) is the position on the screen of the upper left corner of the window.
2) The coordinates of the lower left corner of the display window are (-1,-1), and the coordinates of the upper right corner are (1,1).
2. Add keyboard interaction on the basis of Experiment 1, press the W key to move the drawn rectangle up, press the S key to move the rectangle down, press the A key to move the rectangle to the left, and press the D key to move the rectangle to the right, as shown in Experimental Figure 3-2 . The reference steps are as follows:
1) Add a keyboard registration callback function in the main function:
glutKeyboardFunc(mykeyboard);
This function can be placed after glutDisplayFunc(display).
2) Modify the rectangle drawing code in the display () drawing function, and replace the numerical parameters with variables.
For example:
glRectf(-0.5,-0.5,0.5,0.5);
Change to:
add variable declaration and initial value before the program, such as:
float xl=-0.5,yl=-0.5,x2=0.5,y2=0.5 ;
Note the position of the statement.
3) Add the mykeyboard keyboard sub-function in the program, and modify it in the following code to realize the movement of the keyboard to control the rectangle, and run the program to test itself.

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();
}

insert image description here
insert image description here
insert image description here
insert image description here
3. Set the window change callback function so that the length and width of the rectangle are equal to 100. When the program starts, the rectangle is still in the center of the window. When the display window is maximized, the drawn rectangle also increases, as shown in Figure 3-3.
1) Add a registered window change function in the main function:
glutReshapeFunc (myreshape); // before glutMainLoop ()
2) Add a window change sub-function in the program, the parameters W and h are the width and height of the current display window:

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

3) At this point, the initial variable of the rectangle is recalculated as:
float x1= ​​100, x1=100, x2=200, y2=200;
Note: readers are asked to think about why the initial variable of the rectangle is changed from the original (-0.5,- 0.5, 0.5, 0.5) becomes (100, 100, 200, 200)?
What are the rules for setting the cropping window setting function gluOrtho2D (xwmin, xwmax, ywmin, ywmax) and the viewport setting function glView-port (startx, starty, viewport_width, viewport_height)?
Answer: It is caused by the function glOrtho. The purpose of this function is to set or trim the extent of the space. The syntax is: void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdoublefar); left means the leftmost coordinate, right means the rightmost coordinate, bottom means the bottommost coordinate, top means the topmost Coordinates, near means the coordinates of the front edge, and far means the coordinates of the last edge.

At this point, press the keyboard W, A, D, and S keys to move interactively. How does the moving distance of the rectangle change compared to before? How should the program be modified to maintain the previous frequency of movement?
A: Get smaller and barely move. Modifies the rectangle diagonal coordinate variable.
Before the display window is changed:
insert image description here
After the display window is changed:
insert image description here
4. Add the character "Hello" in the middle of the rectangle and observe the result; then change the character "Hello" to the pinyin or English name of your own name. As shown below.
Tip: Add the following code after drawing the rectangle.

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"

insert image description here
Note: Run the program, the effect is as shown in the figure above. But if you press the W, A, D, and S keys on the keyboard to move interactively, what will happen to the program? How should the program be modified to keep the rectangle white and the characters red?
A: The text moves with the characters. Rectangles and text define different colors
If the character color setting statement glColor3f(1,0,0) is placed after the position cursor statement glRasterPos2i((xl1+x2)/2,(y1+y2)/2), what will happen when it runs Variety? Readers are asked to summarize the order of the character color statement by themselves.
A: The characters are blocked and there is only one rectangle. The character color setting needs to be before the positioning cursor statement.

5. Refer to the textbook to draw a two-dimensional plane figure according to your own ideas, replace the above rectangle with the two-dimensional plane figure you conceived to realize the interactive function, pay attention to the order of the vertices, and mark your name on the screen.
code:

#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;
}

Experimental results:
insert image description here

3. Thinking questions

Follow these steps and analyze the relationship between cropping window, viewport and display window.
1) Modify the size of the viewport to half of the original size, as shown in the figure.
2) Modify the size of the cropping window to half of the original size; the viewport remains unchanged, as shown in the figure.
Reference function:
・Cropping window setting function:
gluOrtho2D (xwmin, xwmax, ywmin, ywmax) ; //xwmin xwmax, ywmin, ywmax are the positions of the clipping window in the world coordinate system, respectively x minimum, x maximum, y minimum, y Maximum
• viewport setting function:
glViewport (startx, starty, viewport_width, viewport_height) ;//The position of the drawing area in the display window, taking the screen coordinate system as a reference, startx, starty.viewport_widthviewport_height are the starting points of the drawing area in the display window Position, as well as the width and height of the drawing area
insert image description here
insert image description here
3) Modify the above program so that press the number 1 key to realize the rectangle, use the W, S, A, D keys to control the up, down, left and right movement, and press the 2 key to display other 2D graphics conceived by yourself (triangle, point or polygon, etc.), use W, S, A, D keys to control up, down, left and right movement.
Code modification:

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();
}

insert image description here

Guess you like

Origin blog.csdn.net/weixin_52030647/article/details/130726696