当前位置:网站首页>Coordinate transformation learning of OpenGL learning notes

Coordinate transformation learning of OpenGL learning notes

2022-06-21 11:14:00 clever101

author : Zhu Jincan
source :clever101 The column

GDI、Qt and OpenGL The drawing difference between the three

   Begin to learn OpenGL Step over some potholes . Because I've learned GDI and Qt mapping .GDI and Qt Drawings are more intuitive . As shown in the following figure GDI Draw a line from (0,0) To (100,100) The straight line of :
GDI Drawing examples
The drawing code is as follows :

HPEN  g_hPen = NULL;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
    switch (message)
    {
    
	case WM_CREATE:
	{
    
		g_hPen = CreatePen(PS_SOLID,2,RGB(255,0,0));
		break;
	}
    case WM_PAINT:
        {
    
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO:  Add here to use  hdc  Any drawing code for ...
			SelectPen(hdc, g_hPen);
            // from (0,0) To (100,100) Draw a straight line 
			::MoveToEx(hdc, 0, 0, NULL);
			::LineTo(hdc, 100, 100);
			// With (100, 100) Draw a radius for the center of the circle 4 The circle of 
            ::Ellipse(hdc,96,96,104,104);
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
	{
    
		DeletePen(g_hPen);
		PostQuitMessage(0);
	}
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

   You can see GDI Coordinates in drawing (0,0) It's in the upper left corner of the window . Let's try again Qt mapping ,Qt The rendering of the drawing is as follows :
Qt Drawing examples

The drawing code is as follows :

void QtDraw::paintEvent(QPaintEvent *)
{
    
	QPainter painter(this);
	painter.setPen(QPen(Qt::red, 4));// Set brush form 
	painter.drawLine(0, 0, 100, 100);// from (0,0) To (100,100) Draw a straight line 
	painter.drawEllipse(100, 100, 4, 4);// With (100,100) For the center of a circle , The radius is 4 A circle 
}

   You can see Qt Coordinates in drawing (0,0) It's in the upper left corner of the window . Let's see OpenGL The graph function of . On the surface ,OpenGL The code for drawing straight lines is also very simple , as follows :

glBegin(GL_LINES);
 glVertex2f(0, 0);
 glVertex2f(100, 100);
glEnd();

   But the above code can not draw from the window (0,0) To (100,100) The straight line of . That is to say glVertex2f The parameter of the function does not accept the coordinates of the window coordinate system . This is with GDI and Qt There is a fundamental difference .

OpenGL Coordinate conversion process

   We know from the last section that glVertex2f The parameter of the function does not accept the coordinates of the window coordinate system . So here comes the question ,glVertex2f In which coordinate system is the parameter value of the function ? After studying, we found that ,glVertex2f The parameter value of the function is in the coordinates of the object . Here comes the question , How is the object coordinate converted to the window coordinate system ? After reading 《OpenGL Programming Guide 》, The discovery process is as follows :
OpenGL Coordinate conversion process
   Here comes the question , If we want to use OpenGL Draw a line from... On the window (0,0) To (100,100) The straight line of , What should be done ? According to the above process , That is to say, we should (0,0) and (100,100) Perform an inverse transformation , Transform these two points from window coordinates to object coordinates . The code is as follows :

void DrawGLScene(GLvoid)								
{
    
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			//  Clear screen and depth cache 
    glColor3f(1.0f, 0.0f, 0.0f);

	GLint viewport[4];
	// Get the range of the current viewport 
	glGetIntegerv(GL_VIEWPORT, viewport);
	GLdouble modelview[16];
	GLdouble projection[16];

	GLdouble winStartX = 0.0;
	GLdouble winStartY = 0.0;

	GLdouble winEndX = 100.0;
	GLdouble winEndY = 100.0;

	GLdouble objStartX, objStartY, objStartZ;
	GLdouble objEndX, objEndY, objEndZ;
	// Get the view and model transformation matrix 
	glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	// Get the projection matrix 
	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	// Convert window coordinates to object coordinates 
	gluUnProject(winStartX, winStartY, 0.0, modelview, projection, viewport, &objStartX, &objStartY, &objStartZ);
	gluUnProject(winEndX, winEndY, 0.0, modelview, projection, viewport, &objEndX,&objEndY,&objEndZ);

	// Perform drawing 
	glBegin(GL_LINES);
	glVertex2f(objStartX, objStartY);
	glVertex2f(objEndX, objEndY);
    glEnd();
}

The renderings are as follows :
OpenGL Draw a straight line

  OpenGL Window coordinates in drawing (0,0) It's in the lower left corner of the window , We can see that our code drawing is correct .

原网站

版权声明
本文为[clever101]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206211056093923.html