SAMPLE: Rendering a Triangle Using an Execute BufferLast reviewed: September 5, 1997Article ID: Q169769 |
The information in this article applies to:
SUMMARYEBTri is a sample that demonstrates Direct3D Immediate Mode to render a triangle using an execute buffer. To close the application, press the Esc key or Alt+F4 keys. The following file is available for download from the Microsoft Software Library:
~ D3debtri.exe (size: 55902 bytes)For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q119591 TITLE : How to Obtain Microsoft Support Files from Online Services MORE INFORMATIONThe following files are created when you run the self-executable file:
How the Sample WorksThe following discussion is "walk you through" the code. The entry point of the sample is the same as any other Windows application, WinMain(). This is where all initialization takes place for the sample. The first initialization step is registering the window class and creating the window. After the window is created successfully, then an infinite message loop is entered until the application is closed. DirectX applications (particularly games) should only "run" when the application has the activation. If the application loses activation, or is paused, the application should just process Window's messages instead of running the game loop and trying to render. There aren't any differences when you register the window class for a DirectX application. The sample registers the class with an icon. This icon is used by Windows to visibly represent the application on the task bar when the application loses activation with a task switch. No menu is used since the sample is a full-screen exclusive mode application. After the standard CreateWindow, ShowWindow, and UpdateWindow calls, the sample initializes DirectDraw and Direct3D in InitDDrawAndD3D(). The window callback procedure processes window messages. WM_ACTIVATEAPP must be handled for a "well-behaved" application. When the application loses activation, set a flag and do not enter the game loop. Let the other applications use the CPU for a while. When the application gains activation, make sure to restore the application's internal status including DirectX. Hide Window's cursor in the WM_SETCURSOR case as described. All DirectDraw applications should render their own cursor. Do not let Windows handle cursor rendering unless a flickering cursor is a feature of the application. Determine the cursor position with GetCursorPos then render your own software cursor. All the other messages are self- explanatory. Initializing DirectDraw and Direct3D can be complex. The sample uses a user- defined data structure to hold some global info. The key words for initialization are "never assume anything about the hardware". Following are the steps needed to initialize DirectDraw and Direct3D:
To set up the matrices, you need to define the world, view, and projection matrices, and then associate them with the D3DDEVICE with CreateMatrix and SetMatrix. In SetupLightAndViewport function, a directional light is created and a viewport is setup to map the 3D world to the visible 2D window. To give the triangle and background some visual appeal, it needs to have colors to define each. D3D materials are used for this purpose. If you use 3D hardware acceleration, the color of the triangle will be green. If you use software, the color will be red. On DX5, if MMX is detected, the triangle will be yellow. The background will always be blue. To create an execute buffer, applications should first query the device's HAL to determine the maximum execute buffer size. In the case of the hardware device, the value is either zero or greater than zero. If the value is zero, the device will support any size. "Well-behaved" applications should always calculate the exact size needed by counting everything that will be put in the execute buffer (as shown in the sample code). In the case of a software device, calculate the execute buffer size. Create the execute buffer, and then lock the buffer down for use. To determine where in the execute buffer the vertex list ends and the instruction stream begins, save the pointer to where the execute buffer starts to perform some calculation at the end. Use another pointer to keep track of where the next data stream should be copied to the execute buffer. Start filling the execute buffer by copying the vertex list. The sample renders only one triangle so copy 3 D3DVERTEX to the execute buffer. Note that the sample depends on D3D to perform transformation and light the vertices. After the vertex list is copied to the execute buffer, cache the location of where the vertex list ends and instruction stream begins. The first instruction that is stuffed in the execute buffer sets the lighting module, D3DOP_STATELIGHT. Each instruction is followed by one or more data units (D3DSTATE). For the lighting module, a D3DINSTRUCTION is followed by a D3DSTATE to specify the light state type. You specify the world, view, and projection transforms with D3DOP_STATETRANSFORM. The data follows the instruction, which are 3 D3DSTATE that contain the handles to the world, view, and projection matrices created earlier. You turn on the Gouraud shade by specifying D3DOP_STATERENDER instruction with D3DRENDERSTATE_SHADEMODE data. Specify that the vertices need to be transformed and lit by D3D with D3DOP_PROCESSVERTICES and D3DPROCESSVERTICES_TRANSFORMLIGHT data. Send out the triangle with D3DOP_TRIANGLE and specify an edge-enabled triangle with D3DTRIFLAG_EDGEENABLETRIANGLE. Terminate the execute buffer with D3DOP_EXIT, and then unlock the execute buffer. Before the execute buffer can be executed, the contents (how many vertices, where does the instruction code begin, how long is the instruction buffer) of the execute buffer needs to be described with SetExecuteData. After the execute buffer is created, then you can render the triangle. First, clear the viewport and Z-buffer with Clear. Then render the triangle with BeginScene, Execute, and EndScene. Those four APIs are usually called together in the sequence shown. With each frame, the triangle is animated by modifying the world matrix to apply a rotation around the Y axis, and then the following four rendering calls:
IDirect3DViewport::Clear IDirect3DDevice::BeginScene IDirect3DDevice::Execute IDirect3DDevice::EndSceneThe image is made visible with a call to IDirectDrawSurface::Flip. During execution the application may be deactivated and switched away. Make sure to pause all processing as mentioned earlier. When the application is re-activated, restore all surfaces and reload any art work onto respective surfaces. The sample doesn't use any textures so IDDrawSurface::Restore is sufficient. When you clean up, release all objects in the reverse order of creation. Notice that only the front buffer is released, not the back nor the Z- buffer. If you release a surface with attached surfaces, all attached surfaces will be released. Keywords : GdiDirect3D GdiDirectDraw kbsample Technology : kbDirectXSDK Version : 3.0 Platform : WINDOWS Solution Type : kbfile |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |