• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            Direct3D中的繪制(2)

            3.2 渲染狀態(tài)

            Direct3D提供了多種渲染狀態(tài),它影響幾何物體怎樣被渲染。渲染狀態(tài)有默認(rèn)值,因此假如你的應(yīng)用程序需要不同于默認(rèn)設(shè)置的渲染時(shí),你僅僅改變它即可。一種渲染效果會(huì)一直起作用,直到你下一次改變渲染狀態(tài)為止。為了設(shè)置一個(gè)渲染狀態(tài),我們使用下面的方法:

            Sets a single device render-state parameter.

            HRESULT SetRenderState(
            D3DRENDERSTATETYPE State,
            DWORD Value
            );

            Parameters

            State
            [in] Device state variable that is being modified. This parameter can be any member of the D3DRENDERSTATETYPE enumerated type.
            Value
            [in] New value for the device render state to be set. The meaning of this parameter is dependent on the value specified for State. For example, if State were D3DRS_SHADEMODE, the second parameter would be one member of the D3DSHADEMODE enumerated type.

            Return Values

            If the method succeeds, the return value is D3D_OK. D3DERR_INVALIDCALL is returned if one of the arguments is invalid.

             

            例如,在下面的例子中我們將使用線框模式渲染我們的物體。因此,我們?cè)O(shè)置如下的渲染狀態(tài):

            _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

            注意:查看DirectX SDK中關(guān)于D3DRENDERSTATETYPE的信息。其中詳細(xì)介紹了所有的渲染狀態(tài)。

             

            3.3 繪制準(zhǔn)備

            一旦我們創(chuàng)建好一個(gè)頂點(diǎn)緩存以及一個(gè)索引緩存(可選的)后,我們就為渲染其中的內(nèi)容準(zhǔn)備得差不多了,但是在渲染前我們還有3個(gè)步驟必須先做。

            1、 設(shè)置資源流。設(shè)置資源流與一個(gè)頂點(diǎn)緩存掛鉤,此流就是一個(gè)流入渲染管線的幾何信息的流。

            下面的方法是用于設(shè)置一個(gè)資源流:

            HRESULT IDirect3DDevice9::SetStreamSource(

                   UINT StreamNumber,

                   IDirect3DVertexBuffer9* pStreamData,

                   UINT OffsetInBytes,

                   UINT Stride

            );

            StreamNumber——確定我們的頂點(diǎn)緩存與哪一個(gè)資源流掛鉤。我們不使用多重流;因此我們總是使用0號(hào)流。

            pStreamData——一個(gè)指向我們想與流掛鉤的那個(gè)頂點(diǎn)緩存的指針。

            OffsetInBytes——相對(duì)流開(kāi)始處的偏移量。以字節(jié)為單位,它指定被填入渲染管線的頂點(diǎn)數(shù)據(jù)的開(kāi)始位置。通過(guò)檢查D3DCAPS9結(jié)構(gòu)中的D3DDEVCAPS2_STREAMOFFSET標(biāo)志,假如你的設(shè)備支持,那么這個(gè)參數(shù)就有一些非0值。

            Stride——我們?cè)陧旤c(diǎn)緩存中操作的每個(gè)部分的流的字節(jié)大小。

            例如,假設(shè)vb是一個(gè)已經(jīng)填充了頂點(diǎn)信息的頂點(diǎn)緩存:

            _device->SetStreamSource( 0, vb, 0, sizeof( Vertex ) );

             

            2、 設(shè)置索引緩存。假如我們使用了索引緩存,我們必須設(shè)置后面要用于繪制操作的索引緩存。每次我們只能使用一個(gè)索引緩存;因此假如你需要用一個(gè)不同的索引緩存繪制一個(gè)物體時(shí),你必須轉(zhuǎn)換到另一個(gè)上。下面的代碼設(shè)置一個(gè)索引緩存:

            _device->SetIndices( _ib ); // 傳遞一個(gè)索引緩存指針的拷貝

             

            3.4用頂點(diǎn)/索引緩存繪制

            在我們創(chuàng)建好頂點(diǎn)/索引緩存以及做好準(zhǔn)備工作以后,我們就能繪制我們的幾何物體了。這是通過(guò)使用DrawPrimitive或者DrawIndexedPrimitive傳送幾何信息到達(dá)渲染管線。這些方法從頂點(diǎn)流中獲得頂點(diǎn)信息以及從索引緩存中獲得索引信息。

             

            3.4.1 IDirect3DDevice9::DrawPrimitive

            這個(gè)方法不使用索引信息繪制圖元。

            HRESULT IDirect3DDevice9::DrawPrimitive(

                   D3DPRIMITIVETYPE PrimitiveType,

                   UINT StartVertex,

                   UINT PrimitiveCount

            );

            PrimitiveType——我們繪制的圖元類型。比如,我們能繪制點(diǎn)和線以及三角形。以后我們使用三角形,用D3DPT_TRIANGLELIST參數(shù)。

            StartVertex——索引到在頂點(diǎn)流中的一個(gè)元素。設(shè)置渲染頂點(diǎn)中的開(kāi)始點(diǎn)。這個(gè)參數(shù)給予我們一定的機(jī)動(dòng)性,可以繪制一個(gè)頂點(diǎn)緩存中的某部分。

            PrimitiveCount——繪制圖元的個(gè)數(shù)。

            例子:

            // 繪制4個(gè)三角形

            _device->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 4);

             

            Renders a sequence of nonindexed, geometric primitives of the specified type from the current set of data input streams.

            HRESULT DrawPrimitive(
            D3DPRIMITIVETYPE PrimitiveType,
            UINT StartVertex,
            UINT PrimitiveCount
            );

            Parameters

            PrimitiveType
            [in] Member of the D3DPRIMITIVETYPE enumerated type, describing the type of primitive to render.
            StartVertex
            [in] Index of the first vertex to load. Beginning at StartVertex the correct number of vertices will be read out of the vertex buffer.
            PrimitiveCount
            [in] Number of primitives to render. The maximum number of primitives allowed is determined by checking the MaxPrimitiveCount member of the D3DCAPS9 structure. PrimitiveCount is the number of primitives as determined by the primitive type. If it is a line list, each primitive has two vertices. If it is a triangle list, each primitive has three vertices.

            Return Values

            If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

            Remarks

            When converting a legacy application to Direct3D 9, you must add a call to either IDirect3DDevice9::SetFVF to use the fixed function pipeline, or IDirect3DDevice9::SetVertexDeclaration to use a vertex shader before you make any Draw calls.

            Defines the primitives supported by Direct3D.

            typedef enum D3DPRIMITIVETYPE
            {
            D3DPT_POINTLIST = 1,
            D3DPT_LINELIST = 2,
            D3DPT_LINESTRIP = 3,
            D3DPT_TRIANGLELIST = 4,
            D3DPT_TRIANGLESTRIP = 5,
            D3DPT_TRIANGLEFAN = 6,
            D3DPT_FORCE_DWORD = 0x7fffffff,
            } D3DPRIMITIVETYPE, *LPD3DPRIMITIVETYPE;

            Constants

            D3DPT_POINTLIST
            Renders the vertices as a collection of isolated points. This value is unsupported for indexed primitives.
            D3DPT_LINELIST
            Renders the vertices as a list of isolated straight line segments.
            D3DPT_LINESTRIP
            Renders the vertices as a single polyline.
            D3DPT_TRIANGLELIST

            Renders the specified vertices as a sequence of isolated triangles. Each group of three vertices defines a separate triangle.

            Back-face culling is affected by the current winding-order render state.

             

            D3DPT_TRIANGLESTRIP
            Renders the vertices as a triangle strip. The backface-culling flag is automatically flipped on even-numbered triangles.
            D3DPT_TRIANGLEFAN
            Renders the vertices as a triangle fan.
            D3DPT_FORCE_DWORD
            Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.

            Remarks

            Using Triangle Strips (Direct3D 9) or Triangle Fans (Direct3D 9) is often more efficient than using triangle lists because fewer vertices are duplicated.

            3.4.2 IDirect3DDevice9::DrawIndexedPrimitive

            這個(gè)方法使用索引信息來(lái)繪制圖元。

            HRESULT IDirect3DDevice9::DrawIndexedPrimitive(

                   D3DPRIMITIVETYPE Type,

                   INT BaseVertexIndex,

                   UINT MinIndex,

                   UINT NumVertices,

                   UINT StartIndex,

                   UINT PrimitiveCount

            );

            Type——我們繪制的圖元類型。比如,我們能繪制點(diǎn)和線以及三角形。以后我們使用三角形,用D3DPT_TRIANGLELIST參數(shù)。

            BaseVertexIndex——一個(gè)基本數(shù)字,在調(diào)用中用它去加上索引。參看下面的說(shuō)明。

            MinIndex——將被引用的最小索引值。

            NumVertices——在此調(diào)用中將被引用的頂點(diǎn)數(shù)。

            StartIndex——索引到索引緩存中的某個(gè)位置,它標(biāo)記開(kāi)始渲染的開(kāi)始索引點(diǎn)。

            PrimitiveCount——繪制圖元的個(gè)數(shù)。

            例子:

            _device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);

             

            注意:BaseVertexIndex參數(shù)需要一些特別的解釋。在解釋過(guò)程中將會(huì)用到的圖3.2。

             

            在索引緩存中定位頂點(diǎn)相應(yīng)的也就在頂點(diǎn)緩存中定位了。然而,假設(shè)我們想將球,盒子,圓柱體的頂點(diǎn)放置到一個(gè)公共的頂點(diǎn)緩存中。對(duì)于每一個(gè)物體,我們將不得不再計(jì)算在公共頂點(diǎn)緩存中的索引。這個(gè)新的索引值是通過(guò)與一個(gè)偏移量相加得到。注意這個(gè)偏移量是標(biāo)準(zhǔn)的頂點(diǎn),而不是字節(jié)。

                   我們需要計(jì)算物體在公共頂點(diǎn)緩存中的索引值。Direct3D允許我們通過(guò)設(shè)置BaseVertexIndex參數(shù)得到一個(gè)頂點(diǎn)偏移量,隨后Direct3D就能利用頂點(diǎn)自身的索引重新計(jì)算新的索引。

             

            3.4.3 開(kāi)始/結(jié)束場(chǎng)景

            最后一點(diǎn)就是所有繪制方法都必須在IDirect3DDevice9::BeginScene和IDirect3DDevice9::EndScene方法之間被調(diào)用。例如,我們將這樣寫(xiě):

            _device->BeginScene();

            // 繪制場(chǎng)景

            _device->DrawPrimitive(...);

            _device->EndScene();

             

            3.5 D3DX幾何物體

            通過(guò)在代碼中建造每個(gè)三角形來(lái)建造3D物體是一件非常枯燥的事。幸運(yùn)的是,D3DX庫(kù)已經(jīng)為我們提供了一些方法來(lái)產(chǎn)生簡(jiǎn)單3D物體的網(wǎng)格數(shù)據(jù)。

            D3DX庫(kù)提供如下6種網(wǎng)格生成函數(shù)。

            D3DXCreateBox

            D3DXCreateSphere

            D3DXCreateCylinder

            D3DXCreateTeapot

            D3DXCreatePolygon

            D3DXCreateTorus

            這6種函數(shù)的使用都很類似,并且使用D3DX網(wǎng)格數(shù)據(jù)結(jié)構(gòu)ID3DXMesh就象使用ID3DXBuffer接口一樣。現(xiàn)在,我們忽視它們的詳細(xì)信息,只需簡(jiǎn)單使用它們即可。

            HRESULT D3DXCreateTeapot(

                   LPDIRECT3DDEVICE9 pDevice, // 與mesh關(guān)聯(lián)的設(shè)備

                   LPD3DXMESH* ppMesh, // 返回的mesh

                   LPD3DXBUFFER* ppAdjacency // 現(xiàn)在設(shè)成0

            );

             

            一個(gè)使用D3DXCreateTeapot函數(shù)的例子:

            ID3DXMesh* mesh = 0;

            D3DXCreateTeapot(_device, &mesh, 0);

            一旦生成了網(wǎng)格數(shù)據(jù),我們就能使用ID3DXMesh::DrawSubset方法繪制圖形了。這個(gè)方法有一個(gè)參數(shù),它用來(lái)識(shí)別網(wǎng)格的一個(gè)子集。這個(gè)網(wǎng)格是通過(guò)上面的D3DXCreate*函數(shù)中的一個(gè)子集創(chuàng)建的,因此可以給這個(gè)參數(shù)指定0值。一個(gè)渲染網(wǎng)格的例子:

            _device->BeginScene();

                   mesh->DrawSubset(0);

            _device->EndScene();

             

            使用了網(wǎng)格以后,必須釋放(release)它:

            mesh->Release();

            _mesh = 0;

             

             

             實(shí)例程序:三角形

            這是非常簡(jiǎn)單的應(yīng)用程序,它示范了在線框模式下怎樣創(chuàng)建并渲染一個(gè)三角形。

            /**************************************************************************************
              Renders a triangle in wireframe mode.  
              Demonstrates vertex buffers, render states, and drawing commands.
             *************************************************************************************
            */

            #include 
            "d3dUtility.h"

            #pragma warning(disable : 
            4100)

            const int WIDTH  = 640;
            const int HEIGHT = 480;

            IDirect3DDevice9
            *        g_d3d_device  = NULL;
            IDirect3DVertexBuffer9
            *    g_triangle_vb = NULL;

            class cVertex
            {
            public:
                
            float m_x, m_y, m_z;

                cVertex() {}

                cVertex(
            float x, float y, float z)
                {
                    m_x 
            = x;
                    m_y 
            = y;
                    m_z 
            = z;
                }
            };

            const DWORD VERTEX_FVF = D3DFVF_XYZ;

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            bool setup()
            {    
                g_d3d_device
            ->CreateVertexBuffer(3 * sizeof(cVertex), D3DUSAGE_WRITEONLY, VERTEX_FVF, 
                                                 D3DPOOL_MANAGED, 
            &g_triangle_vb, NULL);

                
            // fill the buffers with the triangle data
                cVertex* vertices;
                g_triangle_vb
            ->Lock(00, (void**)&vertices, 0);
                
                vertices[
            0= cVertex(-1.0f0.0f2.0f);
                vertices[
            1= cVertex( 0.0f1.0f2.0f);
                vertices[
            2= cVertex( 1.0f0.0f2.0f);

                g_triangle_vb
            ->Unlock();

                
            // set the projection matrix
                D3DXMATRIX proj;
                D3DXMatrixPerspectiveFovLH(
            &proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f1000.0f);
                g_d3d_device
            ->SetTransform(D3DTS_PROJECTION, &proj);

                
            // set wireframe mode render state
                g_d3d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

                
            return true;
            }

            void cleanup()
            {
                safe_release
            <IDirect3DVertexBuffer9*>(g_triangle_vb);
            }

            bool display(float time_delta)
            {
                g_d3d_device
            ->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff1.0f0);

                g_d3d_device
            ->BeginScene();

                g_d3d_device
            ->SetStreamSource(0, g_triangle_vb, 0sizeof(cVertex));
                g_d3d_device
            ->SetFVF(VERTEX_FVF);

                
            // draw one triangle
                g_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 01);

                g_d3d_device
            ->EndScene();

                g_d3d_device
            ->Present(NULL, NULL, NULL, NULL);

                
            return true;
            }

            LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
            {
                
            switch(msg)
                {
                
            case WM_DESTROY:
                    PostQuitMessage(
            0);
                    
            break;

                
            case WM_KEYDOWN:
                    
            if(word_param == VK_ESCAPE)
                        DestroyWindow(hwnd);
                    
            break;
                }

                
            return DefWindowProc(hwnd, msg, word_param, long_param);
            }

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
            {
                
            if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
                {
                    MessageBox(NULL, 
            "init_d3d() - failed."0, MB_OK);
                    
            return 0;
                }

                
            if(! setup())
                {
                    MessageBox(NULL, 
            "Steup() - failed."0, MB_OK);
                    
            return 0;
                }

                enter_msg_loop(display);

                cleanup();
                g_d3d_device
            ->Release();

                
            return 0;
            }

             


            截圖:


            下載三角形源程序


            posted on 2008-03-14 13:00 lovedday 閱讀(1282) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            久久国产亚洲高清观看| 国产精品久久久天天影视| 伊人情人综合成人久久网小说| 久久亚洲精品无码播放| 久久久久波多野结衣高潮| AV无码久久久久不卡蜜桃| 亚洲精品视频久久久| 2022年国产精品久久久久| 一级a性色生活片久久无少妇一级婬片免费放| 狠狠色丁香久久婷婷综合| 91精品国产91久久久久久| 亚洲精品无码久久久久久| 美女久久久久久| 久久精品成人免费看| 精品久久久无码21p发布| 国产ww久久久久久久久久| 久久亚洲精品成人av无码网站| 久久久久亚洲AV成人网人人网站| 久久久久高潮毛片免费全部播放| 婷婷久久综合九色综合绿巨人| 青青草原1769久久免费播放| 色综合久久无码中文字幕| 久久久亚洲裙底偷窥综合| 久久精品夜色噜噜亚洲A∨ | 伊人久久大香线蕉av一区| 久久久久亚洲?V成人无码| 亚洲国产精品久久久久婷婷软件 | 久久亚洲国产成人影院| 精品国产综合区久久久久久| 精品久久久无码人妻中文字幕豆芽| 久久婷婷五月综合国产尤物app| 久久精品成人一区二区三区| 91精品国产综合久久四虎久久无码一级 | 久久人人爽人人爽人人片av麻烦| 久久乐国产精品亚洲综合| 99热精品久久只有精品| 嫩草影院久久99| 久久久99精品成人片中文字幕| 久久久WWW成人免费精品| 国产伊人久久| 日本久久中文字幕|