8-5 drawing with OpenGL)

Source: Internet
Author: User
Tags getcolor

8-5 drawing with OpenGL)OpenGL is a standard API for drawing 2D and 3D models. Based on OpenGL, QT can use the qtopengl module to draw 3D images. This section assumes that you are familiar with OpenGL. If you do not know about OpenGL, you can browse Http://www.opengl.org /.Using OpenGL in QT applications is very simple: we need to inherit our own control classes from qglwidget, implement some virtual functions, and connect to qtopengl and OpenGL libraries. Because qglwidget inherits from qwidget, the previously learned control content still applies. The main difference is that we use OpenGL function plotting instead of qpainter. To illustrate how OpenGL works, let's look at the four-dimensional program as shown in Figure 8.17. This program shows a 3D triangle, each of which is displayed in different colors. You can click the mouse or drag it to rotate it. Double-click a plane to bring up qcolordialog and select another color. Figure 8.17. The tetrahedron Application 

Class tetrahedron: Public qglwidget

{

Q_object

Public:

Tetrahedron (qwidget * parent = 0 );

Protected:

Void initializegl ();

Void resizegl (INT width, int height );

Void paintgl ();

Void mousepressevent (qmouseevent * event );

Void mousemoveevent (qmouseevent * event );

Void mousedoubleclickevent (qmouseevent * event );

PRIVATE:

Void draw ();

Int faceatposition (const qpoint & Pos );

Glfloat rotationx;

Glfloat rotationy;

Glfloat rotationz;

Qcolor facecolors [4];

Qpoint lastpos;

};

Tetrahedron class inherits from qglwidget. initializegl (), resizegl (), and paintgl () are virtual functions inherited from qglwidget. The mouse event processing function is inherited from qwidget.

 

Tetrahedron: tetrahedron (qwidget * parent)

: Qglwidget (parent)

{

Setformat (qglformat (qgl: doublebuffer | qgl: depthbuffer ));

Rotationx =-21.0;

Rotationy =-57.0;

Rotationz = 0.0;

Facecolors [0] = QT: red;

Facecolors [1] = QT: green;

Facecolors [2] = QT: blue;

Facecolors [3] = QT: yellow;

}

In the constructor, call qglwidget: setformat () to determine the OpenGL display mode. Then initialize the private functions of the class.

Void tetrahedron: initializegl ()

{

Qglclearcolor (QT: Black );

Glshademodel (gl_flat );

Glenable (gl_depth_test );

Glable (gl_cull_face );

}

The initializegl () function is called only once before paintgl (). Here, you can set the OpenGL display content to define the display list or other initialization operations.

Qglclearcolor () is a function of qglwidget, and other functions are OpenGL standard functions. If all follows the OpenGL library, you can call the glclearcolor () function and the glclearindex () function in rgba format ().

Void tetrahedron: resizegl (INT width, int height)

{

Glviewport (0, 0, width, height );

Glmatrixmode (gl_projection );

Glloadidentity ();

Glfloat x = glfloat (width)/height;

Glfrustum (-x, x,-1.0, 1.0, 4.0, 15.0 );

Glmatrixmode (gl_modelview );

}

The resizegl () function is called before paintgl (). This function is called whenever the control size changes. In this function, you can set the OpenGL view, projection, and other settings related to the control size.

Void tetrahedron: paintgl ()

{

Glclear (gl_color_buffer_bit | gl_depth_buffer_bit );

Draw ();

}

 

The paintgl () function is called when the control needs to be re-drawn. It is similar to the paintevent () function of the qwidget control. The difference is that the OpenGL function is used when the control is drawn. The actual drawing is implemented by the private function draw.

Void tetrahedron: Draw ()

{

Static const glfloat P1 [3] = {0.0,-1.0, + 2.0 };

Static const glfloat P2 [3] = {+ 1.73205081,-1.0,-1.0 };

Static const glfloat P3 [3] = {-1.73205081,-1.0,-1.0 };

Static const glfloat P4 [3] = {0.0, + 2.0, 0.0 };

Static const glfloat * const coords [4] [3] = {

{P1, P2, P3}, {p1, P3, P4}, {p1, P4, P2}, {P2, P4, P3}

};

Glmatrixmode (gl_modelview );

Glloadidentity ();

Gltranslatef (0.0, 0.0,-10.0 );

Glrotatef (rotationx, 1.0, 0.0, 0.0 );

Glrotatef (rotationy, 0.0, 1.0, 0.0 );

Glrotatef (rotationz, 0.0, 0.0, 1.0 );

For (INT I = 0; I <4; ++ I ){

Glloadname (I );

Glbegin (gl_triangles );

Qglcolor (facecolors [I]);

For (Int J = 0; j <3; ++ J ){

Glvertex3f (coords [I] [J] [0], coords [I] [J] [1],

Coords [I] [J] [2]);

}

Glend ();

}

}

In the draw () function, we draw the triangle by referring to the coordinates of X, Y, Z and the color in facecolor. Except glcolor (), all other functions call the OpenGL library. We can use glcolor3d () or glindex () in OpenGL mode.

Void tetrahedron: mousepressevent (qmouseevent * event)

{

Lastpos = event-> pos ();

}

Void tetrahedron: mousemoveevent (qmouseevent * event)

{

Glfloat dx = glfloat (Event-> X ()-lastpos. X ()/width ();

Glfloat DY = glfloat (Event-> Y ()-lastpos. Y ()/height ();

If (Event-> buttons () & QT: leftbutton ){

Rotationx + = 180 * dy;

Rotationy ++ = 180 * DX;

Updategl ();

} Else if (Event-> buttons () & QT: rightbutton ){

Rotationx + = 180 * dy;

Rotationz ++ = 180 * DX;

Updategl ();

}

Lastpos = event-> pos ();

}

 

The mousepressevent () and mousemoveevent () functions overwrite the qwidget class, allowing you to rotate by clicking or dragging the mouse. Click the left mouse button to rotate along the X and Y axes. Right-click to rotate along the X and Y axes.

After modifying the rotationx variable, rotationy variable, or rotationz variable, call updategl () to re-draw the control.

Void tetrahedron: mousedoubleclickevent (qmouseevent * event)

{

Int face = faceatposition (Event-> pos ());

If (face! =-1 ){

Qcolor color = qcolordialog: getcolor (facecolors [face], this );

If (color. isvalid ()){

Facecolors [face] = color;

Updategl ();

}

}

}

The mousedoubleclickevent () function overrides the qwidget's function of the same name, allowing you to double-click the control to set the color of a surface of the river. The private function faseatposition () is used to obtain the surface of the operator where the cursor is located. If you double-click a plane, call qcolordialog: getcolor () to obtain a new color of the plane. Then, update the facecolors array and call updagegl () to re-draw the control.

Int tetrahedron: faceatposition (const qpoint & Pos)

{

Const int maxsize = 512;

Gluint buffer [maxsize];

Glint viewport [4];

Glgetintegerv (gl_viewport, viewport );

Glselectbuffer (maxsize, buffer );

Glrendermode (gl_select );

Glinitnames ();

Glpushname (0 );

Glmatrixmode (gl_projection );

Glpushmatrix ();

Glloadidentity ();

Glupickmatrix (gldouble (Pos. X (), gldouble (viewport [3]-pos. Y ()),

5.0, 5.0, viewport );

Glfloat x = glfloat (width ()/height ();

Glfrustum (-x, x,-1.0, 1.0, 4.0, 15.0 );

Draw ();

Glmatrixmode (gl_projection );

Glpopmatrix ();

If (! Glrendermode (gl_render ))

Return-1;

Return buffer [3];

}

 

The faceatposition () function returns the plane number of a position in the control. If it is not in the plane,-1 is returned. Using OpenGL to implement code is somewhat complicated. In fact, we use the gl_select mode to draw the triangle, use the OpenGL point acquisition function, and then obtain the plane number.

The following is the implementation code of Main. cpp:

# Include <qapplication>

# Include <iostream>

# Include "tetrahedron. H"

Using namespace STD;

Int main (INT argc, char * argv [])

{

Qapplication app (argc, argv );

If (! Qglformat: hasopengl ()){

Cerr <"this system has no OpenGL support" <Endl;

Return 1;

}

Tetrahedron;

Tetrahedron. setwindowtitle (qobject: TR ("tetrahedron "));

Tetrahedron. Resize (300,300 );

Tetrahedron. Show ();

Return app.exe C ();

}

 

If your system does not support OpenGL, print an error message on the console and exit.

In the. Pro file, the application needs to connect to the qtopengl Library:

Qt + = OpenGL

 

Now, all the programs of this ry are completed. For more information about qtopengl, see qglwidget, qglformat, qglcontext, and qglpixelbuffer.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.