• <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>

            天行健 君子當自強而不息

            網格模型高級技術(7)

            增強網格模型是運行鑲嵌技術將原始網格模型的三角形面進行細分,形成更加精細(三角形面更多)的網格模型,這對于逐頂點進行的光照效果會更好。網格模型鑲嵌技術主要用在層次細節場景中當模型距離觀察者較近時,使模型的顯示更精細。

            增強網格模型可以通過對原始網格模型進行鑲嵌細分模型得到,Direct3D提供了功能函數D3DXTessellateNPatches()來完成這一工作。該函數根據指定的參數,由顯卡的鑲嵌器(tessellator)對網格模型中的多邊形進行細分,從而使原來的三維物體表面變得更加光滑細致。該函數聲明如下:

            Tessellates the given mesh using the N-patch tessellation scheme.

            HRESULT D3DXTessellateNPatches(
            LPD3DXMESH pMeshIn,
            CONST DWORD * pAdjacencyIn,
            FLOAT NumSegs,
            BOOL QuadraticInterpNormals,
            LPD3DXMESH * ppMeshOut,
            LPD3DXBUFFER * ppAdjacencyOut
            );

            Parameters

            pMeshIn
            [in] Pointer to an ID3DXMesh interface, representing the mesh to tessellate.
            pAdjacencyIn
            [in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the source mesh. This parameter may be NULL.
            NumSegs
            [in] Number of segments per edge to tessellate.
            QuadraticInterpNormals
            [in] Set to TRUE to use quadratic interpolation for normals; set to FALSE for linear interpolation.
            ppMeshOut
            [out] Address of a pointer to an ID3DXMesh interface, representing the returned tessellated mesh.
            ppAdjacencyOut
            [out] Address of a pointer to an ID3DXBuffer interface. If the value of this parameter is not set to NULL, this buffer will contain an array of three DWORDs per face that specify the three neighbors for each face in the output mesh. This parameter may be NULL.

            Return Values

            If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following values: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

            Remarks

            This function tessellates by using the N-patch algorithm.

            在示例程序EnhancedMesh中,生成增強網格模型的代碼如下:

            //--------------------------------------------------------------------------------------
            // Generate enhanced mesh from original mesh
            //--------------------------------------------------------------------------------------
            HRESULT GenerateEnhancedMesh(IDirect3DDevice9* device, UINT num_segs)
            {
            ID3DXMesh* enhanced_mesh;
            ID3DXMesh* cloned_mesh;
            HRESULT hr;
            	// use 32 bit index to avoid vertex indices buffer overflow
            V_RETURN(g_mesh->CloneMeshFVF(D3DXMESH_MANAGED | D3DXMESH_32BIT, g_mesh->GetFVF(), device, &cloned_mesh));
            	V_RETURN(D3DXTessellateNPatches(cloned_mesh, (DWORD*) g_adj_buffer->GetBufferPointer(), (float) num_segs,
            FALSE, &enhanced_mesh, NULL));
            	release_com(cloned_mesh);
            release_com(g_enhanced_mesh); // release already used global enhanced mesh
            	g_enhanced_mesh = enhanced_mesh;
            	return S_OK;
            }

            在上面的代碼中,首先調用函數CloneMeshFVF()在原網格模型基礎上進行克隆,這是因為后面將要生成的增強網格模型的頂點和多邊形數量相當大,16位索引可能很難滿足需求,為了防止意外,使用標志D3DXMESH_32BIT克隆出使用32位索引的新網格模型。接下來調用函數D3DXTessellateNPatches()生成增強網格模型。

             

            運行效果圖:

            細分前

             

            每邊細分為2

             

            每邊細分為10

             

            主程序:

            #include "dxstdafx.h"
            #include 
            "resource.h"

            #pragma warning(disable : 
            4127 4995)

            #define IDC_TOGGLE_FULLSCREEN    1
            #define IDC_TOGGLE_REF            2
            #define IDC_CHANGE_DEVICE        3
            #define IDC_SEGMENT                4

            #define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

            ID3DXFont
            *                    g_font;
            ID3DXSprite
            *                g_text_sprite;
            bool                        g_show_help;

            CDXUTDialogResourceManager    g_dlg_resource_manager;
            CD3DSettingsDlg                g_settings_dlg;
            CDXUTDialog                    g_button_dlg;
            CDXUTDialog                    g_ui_dlg;

            ID3DXMesh
            *                    g_mesh;
            D3DMATERIAL9
            *                g_mesh_materials;
            IDirect3DTexture9
            **            g_mesh_textures;
            DWORD                        g_num_materials;
            ID3DXBuffer
            *                g_adj_buffer;
            ID3DXMesh
            *                    g_enhanced_mesh;
            UINT                        g_num_segs 
            = 1;

            //--------------------------------------------------------------------------------------
            // Rejects any devices that aren't acceptable by returning false
            //--------------------------------------------------------------------------------------
            bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                              D3DFORMAT BackBufferFormat, 
            bool bWindowed, void* pUserContext )
            {
                
            // Typically want to skip backbuffer formats that don't support alpha blending

                IDirect3D9
            * pD3D = DXUTGetD3DObject(); 

                
            if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, 
                                D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
                    
            return false;

                
            return true;
            }


            //--------------------------------------------------------------------------------------
            // Before a device is created, modify the device settings as needed.
            //--------------------------------------------------------------------------------------
            bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
            {
                
            // If video card does not support hardware vertex processing, then uses sofaware vertex processing.
                if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

                
            static bool is_first_time = true;

                
            if(is_first_time)
                {
                    is_first_time 
            = false;

                    
            // if using reference device, then pop a warning message box.
                    if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
                        DXUTDisplaySwitchingToREFWarning();
                }

                
            return true;
            }

            //--------------------------------------------------------------------------------------
            // Remove path from fullname, and convert filename from multibyte to wchar.
            //--------------------------------------------------------------------------------------
            void RemovePathFromFileName(LPSTR fullname, LPWSTR wfilename)
            {
                WCHAR wbuf[MAX_PATH]  
            = {0};
                MultiByteToWideChar(CP_ACP, 
            0, fullname, -1, wbuf, MAX_PATH);

                LPWSTR w_last_back_slash 
            = wcsrchr(wbuf, '\\');

                
            if(w_last_back_slash)
                    lstrcpy(wfilename, 
            ++w_last_back_slash);
                
            else
                    lstrcpy(wfilename, wbuf);
            }

            //--------------------------------------------------------------------------------------
            // Generate enhanced mesh from original mesh
            //--------------------------------------------------------------------------------------
            HRESULT GenerateEnhancedMesh(IDirect3DDevice9* device, UINT num_segs)
            {
                ID3DXMesh
            *    enhanced_mesh;
                ID3DXMesh
            *    cloned_mesh;
                HRESULT        hr;

                
            // use 32 bit index to avoid vertex indices buffer overflow
                V_RETURN(g_mesh->CloneMeshFVF(D3DXMESH_MANAGED | D3DXMESH_32BIT, g_mesh->GetFVF(), device, &cloned_mesh));

                V_RETURN(D3DXTessellateNPatches(cloned_mesh, (DWORD
            *) g_adj_buffer->GetBufferPointer(), (float) num_segs,
                                                FALSE, 
            &enhanced_mesh, NULL));

                release_com(cloned_mesh);
                release_com(g_enhanced_mesh);    
            // release already used global enhanced mesh

                g_enhanced_mesh 
            = enhanced_mesh;

                
            return S_OK;
            }

            //--------------------------------------------------------------------------------------
            // Create any D3DPOOL_MANAGED resources here 
            //--------------------------------------------------------------------------------------
            HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, 
                                             
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                             
            void* pUserContext )
            {
                HRESULT    hr;

                V_RETURN(g_dlg_resource_manager.OnCreateDevice(pd3dDevice));
                V_RETURN(g_settings_dlg.OnCreateDevice(pd3dDevice));

                D3DXCreateFont(pd3dDevice, 
            180, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                               DEFAULT_PITCH 
            | FF_DONTCARE, L"Arial"&g_font);

                ID3DXBuffer
            * material_buffer;

                V_RETURN(D3DXLoadMeshFromXW(L
            "cube.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL,
                                            
            &g_num_materials, &g_mesh));

                D3DXMATERIAL
            * xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();
                g_mesh_materials 
            = new D3DMATERIAL9[g_num_materials];
                g_mesh_textures  
            = new IDirect3DTexture9*[g_num_materials];

                
            for(DWORD i = 0; i < g_num_materials; i++)
                {
                    g_mesh_materials[i] 
            = xmaterials[i].MatD3D;
                    g_mesh_materials[i].Ambient 
            = g_mesh_materials[i].Diffuse;

                    WCHAR wfilename[
            256];
                    RemovePathFromFileName(xmaterials[i].pTextureFilename, wfilename);

                    g_mesh_textures[i] 
            = NULL;

                    
            if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0)
                    {
                        V_RETURN(D3DXCreateTextureFromFileW(pd3dDevice, wfilename, 
            &g_mesh_textures[i]));
                    }
                }
                
                material_buffer
            ->Release();

                V_RETURN(GenerateEnhancedMesh(pd3dDevice, g_num_segs));

                
            return S_OK;
            }


            //--------------------------------------------------------------------------------------
            // Create any D3DPOOL_DEFAULT resources here 
            //--------------------------------------------------------------------------------------
            HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                            
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                            
            void* pUserContext )
            {
                HRESULT hr;

                V_RETURN(g_dlg_resource_manager.OnResetDevice());
                V_RETURN(g_settings_dlg.OnResetDevice());
                V_RETURN(g_font
            ->OnResetDevice());
                V_RETURN(D3DXCreateSprite(pd3dDevice, 
            &g_text_sprite));

                
            // set dialog position and size

                g_button_dlg.SetLocation(pBackBufferSurfaceDesc
            ->Width - 1700);
                g_button_dlg.SetSize(
            170170);

                g_ui_dlg.SetLocation(
            0, pBackBufferSurfaceDesc->Height - 60);
                g_ui_dlg.SetSize(pBackBufferSurfaceDesc
            ->Width, 50);
                g_ui_dlg.GetControl(IDC_SEGMENT)
            ->SetSize(pBackBufferSurfaceDesc->Width - 2016);

                
            // setup view matrix

                D3DXMATRIX mat_view;
                D3DXVECTOR3 eye(
            0.0f0.0f,  6.0f);
                D3DXVECTOR3  at(
            0.0f0.0f,  0.0f);
                D3DXVECTOR3  up(
            0.0f1.0f,  0.0f);

                D3DXMatrixLookAtLH(
            &mat_view, &eye, &at, &up);
                pd3dDevice
            ->SetTransform(D3DTS_VIEW, &mat_view);

                
            // set projection matrix
                D3DXMATRIX mat_proj;
                
            float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
                D3DXMatrixPerspectiveFovLH(
            &mat_proj, D3DX_PI/4, aspect, 1.0f100.0f);
                pd3dDevice
            ->SetTransform(D3DTS_PROJECTION, &mat_proj);

                
            return S_OK;
            }

            //--------------------------------------------------------------------------------------
            // Release resources created in the OnResetDevice callback here 
            //--------------------------------------------------------------------------------------
            void CALLBACK OnLostDevice( void* pUserContext )
            {
                g_dlg_resource_manager.OnLostDevice();
                g_settings_dlg.OnLostDevice();
                g_font
            ->OnLostDevice();

                release_com(g_text_sprite);
            }


            //--------------------------------------------------------------------------------------
            // Release resources created in the OnCreateDevice callback here
            //--------------------------------------------------------------------------------------
            void CALLBACK OnDestroyDevice( void* pUserContext )
            {
                g_dlg_resource_manager.OnDestroyDevice();
                g_settings_dlg.OnDestroyDevice();        

                delete[] g_mesh_materials;
                g_mesh_materials 
            = NULL;

                
            if(g_mesh_textures)
                {
                    
            for(DWORD i = 0; i < g_num_materials; i++)
                        release_com(g_mesh_textures[i]);

                    delete[] g_mesh_textures;
                    g_mesh_textures 
            = NULL;
                }

                release_com(g_font);
                release_com(g_adj_buffer);
                release_com(g_mesh);
                release_com(g_enhanced_mesh);    
            }

            //--------------------------------------------------------------------------------------
            // Handle updates to the scene
            //--------------------------------------------------------------------------------------
            void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
            {
                D3DXMATRIX mat_world;
                
            float time = timeGetTime() / 1000.0f;
                D3DXMatrixRotationYawPitchRoll(
            &mat_world, time, time, time);

                pd3dDevice
            ->SetTransform(D3DTS_WORLD, &mat_world);
            }

            //--------------------------------------------------------------------------------------
            // Render the helper information
            //--------------------------------------------------------------------------------------
            void RenderText()
            {
                CDXUTTextHelper text_helper(g_font, g_text_sprite, 
            20);
                
                text_helper.Begin();

                
            // show frame and device states
                text_helper.SetInsertionPos(55);
                text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f0.475f0.0f1.0f) );
                text_helper.DrawTextLine( DXUTGetFrameStats(
            true) );
                text_helper.DrawTextLine( DXUTGetDeviceStats() );

                
            // show other simple information
                text_helper.SetForegroundColor( D3DXCOLOR(1.0f1.0f1.0f1.0f) );
                text_helper.DrawFormattedTextLine(L
            "Divide every edge of original mesh into part: %d\n", g_num_segs);
                text_helper.DrawFormattedTextLine(L
            "Enhanced mesh's faces number: %d\n", g_enhanced_mesh->GetNumFaces());
                text_helper.DrawFormattedTextLine(L
            "Enhanced mesh's vertices number: %d\n", g_enhanced_mesh->GetNumVertices());

                
            // show helper information
                
                
            const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();

                
            if(g_show_help)
                {
                    text_helper.SetInsertionPos(
            10, surface_desc->Height - 15 * 6);
                    text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f0.475f0.0f1.0f) );
                    text_helper.DrawTextLine(L
            "Controls (F1 to hide):");
                    
                    text_helper.SetInsertionPos(
            40, surface_desc->Height - 15 * 4);
                    text_helper.DrawTextLine(L
            "Quit: ESC");
                }
                
            else
                {
                    text_helper.SetInsertionPos(
            10, surface_desc->Height - 15 * 4);
                    text_helper.SetForegroundColor( D3DXCOLOR(
            1.0f1.0f1.0f1.0f) );
                    text_helper.DrawTextLine(L
            "Press F1 for help");
                }

                text_helper.End();
            }

            //--------------------------------------------------------------------------------------
            // Render the scene 
            //--------------------------------------------------------------------------------------
            void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
            {
                HRESULT hr;

                
            if(g_settings_dlg.IsActive())
                {
                    g_settings_dlg.OnRender(fElapsedTime);
                    
            return;
                }

                
            // Clear the render target and the zbuffer 
                V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(009292), 1.0f0) );

                
            // Render the scene
                if( SUCCEEDED( pd3dDevice->BeginScene() ) )
                {
                    
            for(DWORD i = 0; i < g_num_materials; i++)
                    {
                        pd3dDevice
            ->SetMaterial(&g_mesh_materials[i]);
                        pd3dDevice
            ->SetTexture(0, g_mesh_textures[i]);
                        g_enhanced_mesh
            ->DrawSubset(i);
                    }        

                    RenderText();
                    V(g_button_dlg.OnRender(fElapsedTime));
                    V(g_ui_dlg.OnRender(fElapsedTime));

                    V( pd3dDevice
            ->EndScene() );
                }
            }


            //--------------------------------------------------------------------------------------
            // Handle messages to the application 
            //--------------------------------------------------------------------------------------
            LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                                      
            bool* pbNoFurtherProcessing, void* pUserContext )
            {
                
            *pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
                
            if(*pbNoFurtherProcessing)
                    
            return 0;

                
            if(g_settings_dlg.IsActive())
                {
                    g_settings_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
                    
            return 0;
                }

                
            *pbNoFurtherProcessing = g_button_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
                
            if(*pbNoFurtherProcessing)
                    
            return 0;

                
            *pbNoFurtherProcessing = g_ui_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
                
            if(*pbNoFurtherProcessing)
                    
            return 0;

                
            return 0;
            }


            //--------------------------------------------------------------------------------------
            // Handle keybaord event
            //--------------------------------------------------------------------------------------
            void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
            {
                
            if(is_key_down)
                {
                    
            switch(charater)
                    {
                    
            case VK_F1:
                        g_show_help 
            = !g_show_help;
                        
            break;
                    }
                }
            }

            //--------------------------------------------------------------------------------------
            // Handle events for controls
            //--------------------------------------------------------------------------------------
            void CALLBACK OnGUIEvent(UINT eventint control_id, CDXUTControl* control, void* user_context)
            {
                
            switch(control_id)
                {
                
            case IDC_TOGGLE_FULLSCREEN:
                    DXUTToggleFullScreen();
                    
            break;

                
            case IDC_TOGGLE_REF:
                    DXUTToggleREF();
                    
            break;

                
            case IDC_CHANGE_DEVICE:
                    g_settings_dlg.SetActive(
            true);
                    
            break;

                
            case IDC_SEGMENT:
                    g_num_segs 
            = ((CDXUTSlider*) control)->GetValue();
                    GenerateEnhancedMesh(DXUTGetD3DDevice(), g_num_segs);
                    
            break;
                }
            }

            //--------------------------------------------------------------------------------------
            // Initialize dialogs
            //--------------------------------------------------------------------------------------
            void InitDialogs()
            {
                g_settings_dlg.Init(
            &g_dlg_resource_manager);
                g_button_dlg.Init(
            &g_dlg_resource_manager);
                g_ui_dlg.Init(
            &g_dlg_resource_manager);

                g_button_dlg.SetCallback(OnGUIEvent);

                
            int x = 35, y = 10, width = 125, height = 22;

                g_button_dlg.AddButton(IDC_TOGGLE_FULLSCREEN, L
            "Toggle full screen", x, y,         width, height);
                g_button_dlg.AddButton(IDC_TOGGLE_REF,          L
            "Toggle REF (F3)",     x, y += 24, width, height);
                g_button_dlg.AddButton(IDC_CHANGE_DEVICE,      L
            "Change device (F2)", x, y += 24, width, height, VK_F2);

                g_ui_dlg.SetCallback(OnGUIEvent);
                g_ui_dlg.AddSlider(IDC_SEGMENT, 
            1036150241101);
            }

            //--------------------------------------------------------------------------------------
            // Initialize everything and go into a render loop
            //--------------------------------------------------------------------------------------
            INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
            {
                
            // Enable run-time memory check for debug builds.
            #if defined(DEBUG) | defined(_DEBUG)
                _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
            | _CRTDBG_LEAK_CHECK_DF );
            #endif

                
            // Set the callback functions
                DXUTSetCallbackDeviceCreated( OnCreateDevice );
                DXUTSetCallbackDeviceReset( OnResetDevice );
                DXUTSetCallbackDeviceLost( OnLostDevice );
                DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
                DXUTSetCallbackMsgProc( MsgProc );
                DXUTSetCallbackFrameRender( OnFrameRender );
                DXUTSetCallbackFrameMove( OnFrameMove );
                DXUTSetCallbackKeyboard(OnKeyboardProc);
               
                
            // TODO: Perform any application-level initialization here
                InitDialogs();

                
            // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
                DXUTInit( truetruetrue ); // Parse the command line, handle the default hotkeys, and show msgboxes
                DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
                DXUTCreateWindow( L"EnhancedMesh" );
                DXUTCreateDevice( D3DADAPTER_DEFAULT, 
            true640480, IsDeviceAcceptable, ModifyDeviceSettings );

                
            // Start the render loop
                DXUTMainLoop();

                
            // TODO: Perform any application-level cleanup here

                
            return DXUTGetExitCode();
            }

             

            下載示例工程


            posted on 2008-05-28 09:33 lovedday 閱讀(1241) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            99久久久国产精品免费无卡顿| 色综合久久天天综线观看| 久久精品国产亚洲AV久| 精品无码久久久久国产动漫3d| 久久精品亚洲日本波多野结衣| 伊人久久大香线蕉精品| 中文字幕精品久久| 国内精品久久久久久野外| 久久久久久久国产免费看| 一本久道久久综合狠狠爱| 国产成人精品久久| 久久久高清免费视频| 色成年激情久久综合| 少妇熟女久久综合网色欲| 品成人欧美大片久久国产欧美...| 久久综合鬼色88久久精品综合自在自线噜噜| 国产成人无码精品久久久性色| 欧美精品一区二区精品久久 | 久久99国产精品久久99| 亚洲国产成人久久综合区| 亚洲成色999久久网站| 久久亚洲国产成人精品性色| 久久人妻少妇嫩草AV无码蜜桃| 国产综合久久久久| 伊人久久大香线蕉av一区| 久久精品18| 久久精品免费大片国产大片| 99国内精品久久久久久久| 97久久国产亚洲精品超碰热| 少妇人妻88久久中文字幕| 亚洲精品乱码久久久久久按摩 | 欧美精品一区二区精品久久| 久久久精品2019免费观看| 99久久精品国产一区二区| 久久99九九国产免费看小说| 欧美午夜A∨大片久久| 久久久久亚洲AV成人网人人网站 | 精品久久久久久无码中文字幕| 成人午夜精品久久久久久久小说| 亚洲一区二区三区日本久久九| 精品视频久久久久|