Controls, text rendering, and image servers in dxut

Source: Internet
Author: User
Dxut camera

The cmodelviewercamera class in dxut can be used to manage view transformations and perspective transformations, just like GUI functions.

Cmodelviewercamera g_camera; // a model viewing camera

The first feature provided by the camera class is to create a view and perspective matrix. with this camera, there is no need to worry about these matrices. instead, you can specify where you are, what you are looking at, and the size of the window. then, pass these parameters to the camera object, which will create these matrices in the background.

Here we set part of the camera's view parameters. we specify where we are and what we are looking.

// Initialize the camera
D3dxvector3 eye (0.0f, 0.0f,-800366f );
D3dxvector3 at (0.0f, 0.0f, 0.0f );
G_camera.setviewparams (& eye, & );

Next, we will specify the camera projection parameters. that is to say, we need to provide the viewing angle, aspect ratio, and the near and far cropping surface of the view cone. the information is the same as that provided in the previous guide. The difference is that you don't have to worry about how to create a matrix.

// Setup the camera's Projection Parameters
Float faspectratio = pbackbuffersurfacedesc-> width/(float) pbackbuffersurfacedesc-> height;
G_camera.setprojparams (d3dx_pi/4, faspectratio, 0.1f, 5000.0f );
G_camera.setwindow (pbackbuffersurfacedesc-> width, p00backbuffersurfacedesc-> height );

In addition, this camera also encapsulates simple mouse feedback. here, we specify three mouse buttons for mouse operations: Model rotation, contraction, and camera rotation. try to compile the project and use each button to understand each operation.

G_camera.setbuttonmasks (mouse_left_button, mouse_wheel, mouse_middle_button );

On the basis of this button group, the camera listens to these inputs and produces corresponding results. To respond to user input, you need to add a callback function (dxut message processing function) that listens to msgproc ).

// Pass all remaining Windows messages to camera so it can respond to user input
G_camera.handlemessages (hwnd, umsg, wparam, lparam );

Finally, after all the data is input into the camera, it is time to extract the real transformation matrix. here we use the relevant functions to obtain the projection matrix and view matrix. the camera object will calculate these matrices by itself.

G_pprojectionvariable-> setmatrix (float *) g_camera.getprojmatrix ());
G_pviewvariable-> setmatrix (float *) g_camera.getviewmatrix ());

Dxut dialog box

User interaction can be implemented using cdxutdialog. It accepts user input in a dialog box containing controls and passes them through program handles. first, the dialog box class needs to be instantiated before each independent control can be added.

In this Guide, two dialogs will be added. One is g_hud and the d3d10 example share the same code, and the other is g_sampleui to show function details to this guide. the second dialog box is used to control the "fat" of the model, that is, to set a variable to pass to shaders.

Cdxutdialog g_hud; // manages the 3D UI
Cdxutdialog g_sampleui; // Dialog for sample specific controls

These dialogs are controlled by cdxutdialogresourcemanager. This hypervisor transfers messages between the dialogs and processes shared resources.

Cdxutdialogresourcemanager g_dialogresourcemanager; // manager for shared resources of dialogs

Finally, some callback functions are associated with the actual messages processed by the GUI. This function is used to process interactions between controls.

Void callback onguievent (uint nevent, int ncontrolid, cdxutcontrol * pcontrol, void * pusercontext );


 

Dialog Box Initialization

Since many useful things have been introduced, they need to be initialized. This Guide transfers the real initialization of these modules to a separate function called initapp ().

The control of each dialog box is initialized in this function. each dialog box needs to call its initialization function and pass it to the resource manager to specify who the control is provided. similarly, they set callback functions to process GUI responses. in this case, the related callback function is onguievent.

G_hud.init (& g_dialogresourcemanager );
G_sampleui.init (& g_dialogresourcemanager );
G_hud.setcallback (onguievent );
G_sampleui.setcallback (onguievent );

After they are initialized, you can add the control they want to use in each dialog box. in the dialog box, HUD adds three buttons for basic functions: switching full screen, switching the reference (software) Renderer, and changing the device. to add a button, you need to specify the IDC identifier you want to use, a string for display, coordinates, width and height, and optional hotkeys associated with it. you can use the keyboard to quickly switch these buttons for hotkeys.

Note that the specified coordinates are related to the positioning of the dialog box.

Int Iy = 10;
G_hud.addbutton (idc_togglefullscreen, l "toggle full screen", 35, Iy, 125, 22 );
G_hud.addbutton (idc_toggleref, l "toggle REF (F3)", 35, Iy + = 24,125, 22 );
G_hud.addbutton (idc_changedevice, l "change device (F2)", 35, Iy + = 24,125, 22, vk_f2 );

These controls are also added to the sample UI, a static text, a slider, And a check button.
Parameters passed to static text are IDC identifiers, strings, coordinates, and width and height.
The slider parameter is the IDC identifier, String, coordinate, and width and height, as well as the maximum and minimum values of the slider, and finally the variable storing the result.
The check button includes the IDC identifier, a string tag, WF coordinate, width and height, and a Boolean value for storing the result.

Iy = 10;
Wchar SZ [100];
Iy + = 24;
Stringcchprintf (SZ, 100, l "puffiness: % 0.2f", g_fmodelpuffiness );
G_sampleui.addstatic (idc_puff_static, SZ, 35, Iy + = 24,125, 22 );
G_sampleui.addslider (idc_puff_scale, 50, Iy + = 24,100, 22, 0, 2000, (INT) (g_fmodelpuffiness * 100366f ));

Iy + = 24;
G_sampleui.addcheckbox (idc_togglespin, l "toggle spinning", 35, Iy + = 24,125, 22, g_bspinning );

Once initialized, this dialog box will be displayed on the screen. This is done by the ond3d10resizedswapchain call. Every time the screen coordinate changes, this switching chain will be rebuilt (possibly due to window size changes ).

G_hud.setlocation (pbackbuffersurfacedesc-> width-170, 0 );
G_hud.setsize (170,170 );
G_sampleui.setlocation (pbackbuffersurfacedesc-> width-170, pbackbuffersurfacedesc-> height-300 );
G_sampleui.setsize (170,300 );

In the last step of the dialog box, where do you need to identify that they are ond3d10framerender functions? A dialog box is okay if you don't draw it and the user doesn't see it?

//
// Render the UI
//
G_hud.onrender (felapsedtime );
G_sampleui.onrender (felapsedtime );

 

Resource Management Program Initialization

The Resource Management Program needs to be initialized every time the callback is initiated and destroyed. this is because the GUI needs to be re-built each time the device is re-built, or the switching chain needs to be re-built. the cdxutdialogresourcemanager class contains the same name for each callback. therefore, it just inserts code in the right place to call them.

V_return (g_dialogresourcemanager.ond3d10createdevice (pd3ddevice ));
V_return (g_dialogresourcemanager.ond3d10resizedswapchain (pd3ddevice, pbackbuffersurfacedesc ));
G_dialogresourcemanager.ond3d10releasingswapchain ();
G_dialogresourcemanager.ond3d10destroydevice ();



Respond to Gui events

After Initialization is complete, we can finally write code to process GUI interaction. in the initialization dialog box, we set the callback function of these dialog boxes as onguievent. now we will create the onguievent function, which listens to and processes Gui-related events (called by the Framework ).

This is a simple function that contains a case code block for each IDC identifier. It is listened to when a dialog box is created. in each case block, the code is processed, assuming that the user controls it in some way. the processing control code here is similar to the Win32 code.

The control related to the HUD actually calls the built-in function of dxut. there is a dxut function related to switching to full screen, binding to reference the software Renderer, and changing the device settings (it will call the 3D Settings dialog box mentioned below ).

The sampleui dialog box contains the variables associated with the slider for custom code operations. It collects values, updates the text related to the slider, and passes the values to the slider.

Void callback onguievent (uint nevent, int ncontrolid, cdxutcontrol * pcontrol, void * pusercontext)
{

Switch (ncontrolid)
{
Case idc_togglefullscreen: dxuttogglefullscreen (); break;
Case idc_toggleref: dxuttoggleref (); break;
Case idc_changedevice: g_d3dsettingsdlg.setactive (! G_d3dsettingsdlg.isactive (); break;

Case idc_togglespin:
{
G_bspinning = g_sampleui.getcheckbox (idc_togglespin)-> getchecked ();
Break;
}

Case idc_puff_scale:
{
G_fmodelpuffiness = (float) (g_sampleui.getslider (idc_puff_scale)-> getvalue () * 0.01f );

Wchar SZ [100];
Stringcchprintf (SZ, 100, l "puffiness: % 0.2f", g_fmodelpuffiness );
G_sampleui.getstatic (idc_puff_static)-> settext (sz );

G_ppuffiness-> setfloat (g_fmodelpuffiness );
Break;
}
}
}

 


Update message processing

Now that we have dialog box message and user interaction, there will be messages sent to the application to be parsed, if applicable. the code will be processed in the msgproc callback function provided by dxut. in the previous guide, this section is blank because no message needs to be processed. but now, make sure that the messages sent to the Resource Management Program and the dialog box are properly sent.
No special message processing code is required. You only need to call msgprocs for each dialog box to ensure that the message is processed. this is done by calling the corresponding msgproc function of each separate class. it should be noted that this function provides a tag to inform the framework and does not require more processing. Therefore, you can exit.

Lresult callback msgproc (hwnd, uint umsg, wparam, lparam, bool * pbnofurtherprocessing, void * pusercontext)
{
// Always allow dialog Resource Manager callto handle global messages
// So GUI state is updated correctly
* Pbnofurtherprocessing = g_dialogresourcemanager.msgproc (hwnd, umsg, wparam, lparam );
If (* pbnofurtherprocessing)
Return 0;

If (g_d3dsettingsdlg.isactive ())
{
G_d3dsettingsdlg.msgproc (hwnd, umsg, wparam, lparam );
Return 0;
}

// Give the dialogs a chance to handle the message first
* Pbnofurtherprocessing = g_hud.msgproc (hwnd, umsg, wparam, lparam );
If (* pbnofurtherprocessing)
Return 0;

* Pbnofurtherprocessing = g_sampleui.msgproc (hwnd, umsg, wparam, lparam );
If (* pbnofurtherprocessing)
Return 0;

If (umsg = wm_char & wparam = '1 ')
Dxuttogglefullscreen ();

Return 0;
}

 


3D Settings dialog box

A special built-in dialog box is provided to control d3ddevice settings. the dialog box provided by dxut is cd3dsettingsdlg. its function is like a custom dialog box, but it will provide users with all the setting options they need to modify.

Cd3dsettingsdlg g_d3dsettingsdlg; // device Settings dialog

You can call the initialization function just like in other dialog boxes. however, each time direct3d changes its switching chain or device, this dialog box must be updated. therefore, it must contain a call in the ond3d10createdevice and ond3d10resizedswapchain, which corresponds to the name to reflect these changes. similarly, changes to the destroyed object must be reported. Therefore, it must be called in ond3d10destroydevice.

G_d3dsettingsdlg.init (& g_dialogresourcemanager );

V_return (g_d3dsettingsdlg.ond3d10createdevice (pd3ddevice ));
V_return (g_d3dsettingsdlg.ond3d10resizedswapchain (pd3ddevice, pbackbuffersurfacedesc ));

G_d3dsettingsdlg.ond3d10destroydevice ();

On this side of rendering, as the appearance of the dialog box can be changed, it is converted by a tag called isactive. if this tag is set to false, the Panel will not be rendered. the changes to this Panel are handled by the preceding HUD dialog box. mark the idc_changedevice as related to the HUD control, as mentioned above.

If (g_d3dsettingsdlg.isactive ())
{
G_d3dsettingsdlg.msgproc (hwnd, umsg, wparam, lparam );
Return 0;
}

Once these initial steps are completed, you can add this dialog box to your program. compile this guide and interact with the Panel to change the settings to observe its effect. the reconstruction of the real d3ddevice or switching chain is completed in dxut.
 


Text Rendering

A program won't be interesting if the user doesn't know what to do. therefore, dxut contains a tool class used to draw 2D text on the screen for user feedback. this type of cdxutd3d10texthelper allows you to draw a line of text at any position on the screen, with simple string input. before getting started, we need to instantiate this class. since text rendering is independent from most initialization processes, in this guide we will include most of the Code in rendertext10.

Cdxutd3d10texthelper txthelper (g_pfont, g_psprite, 15 );

 

Initialization

The first parameter we input is the font we want to draw. the font type is id3dxfont provided by d3dx. to initialize this font, you call d3dx10createfont, and you need to input the device, height, width, weight, MIP level (generally 1), italic, Character Set, precision, quality, skew and family, font name, and pointer to your object. although it looks like a lot of characters, only the first four and the last two truly make sense.

V_return (d3dx10createfont (pd3ddevice, 15, 0, fw_bold, 1, false, default_charset,
Out_default_precis, default_quality, default_pitch | ff_dontcare,
L "Arial", & g_pfont ));

We need to initialize an id3dxsprite class for the 2nd parameters. To do this, we can call d3dx10createsprite (notice the trend here ?). This function only requires the pointer of the device and object as the parameter.

// Initialize the sprite
V_return (d3dx10createsprite (pd3ddevice, & g_psprite ));

Of course, like other objects, fonts and genie must be destroyed when we complete them. This can be done using the common safe_release macro.

Safe_release (g_pfont );
Safe_release (g_psprite );

 

Rendering

In this example, the rendered statistics are included in the text. In addition, an area shows how to operate the model with the mouse.

Rendering must be called in ond3d10framerender, And in this Guide, it is completed by calling rendertext10 in the frame rendering call.
The first area is being drawn, so it is first completed. the first text rendering call is begin (). it notifies the engine that I want to start outputting text to the screen. after that, we set the position of the pointer and the color of the text, and we are ready to draw.

Call drawtextline to output a string. if you input a string, it will be output at the current position. it adds a pointer while writing the text. Therefore, if Q contains a/N, it automatically moves the pointer to the next row.

// Output statistics
Txthelper. Begin ();
Txthelper. setinsertionpos (2, 0 );
Txthelper. setforegroundcolor (d3dxcolor (1.0f, 1.0f, 0.0f, 1.0f ));
Txthelper. drawtextline (dxutgetframestats ());
Txthelper. drawtextline (dxutgetdevicestats ());

There is another way to output text, as if printf is usually used. You use special characters to format the string and insert the variable into the string. This is achieved through drawformattedtextline.

Txthelper. setforegroundcolor (d3dxcolor (1.0f, 1.0f, 1.0f, 1.0f ));
Txthelper. drawformattedtextline (L "ftime: % 0.1f sin (ftime): % 0.4f", ftime, sin (ftime ));

Since the help plot uses a similar method, you do not need to cover that part of the code. Be sure to re-set the pointer position at any time by calling setinsertionpos.
Finally, when you are satisfied with the text output, call end () to notify the engine of your completion.

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.