C语言调用D3D11示例

由deepseek-r1创作

#pragma once
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <d3d9types.h>
#include <dxgi.h>
#include <math.h>

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "dxgi.lib")

#define WIDTH 800
#define HEIGHT 600

// 常量缓冲结构体
typedef struct {
    D3DMATRIX mWorld;       // 世界矩阵
    D3DMATRIX mView;        // 视图矩阵
    D3DMATRIX mProjection;  // 投影矩阵
} ConstantBuffer;

// 顶点结构体
typedef struct {
    float pos[3];
    float color[4];
} Vertex;

// 全局变量
ID3D11Device* g_pDevice = NULL;
ID3D11DeviceContext* g_pContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;
ID3D11InputLayout* g_pInputLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;
ID3D11Buffer* g_pIndexBuffer = NULL;
ID3D11Buffer* g_pConstantBuffer = NULL;
ID3D11DepthStencilView* g_pDepthStencilView = NULL;
ID3D11RasterizerState* g_pRasterizerState = NULL;

// 矩阵操作函数
void MatrixIdentity(D3DMATRIX* m) {
    memset(m, 0, sizeof(D3DMATRIX));
    m->_11 = m->_22 = m->_33 = m->_44 = 1.0f;
}

void MatrixRotationY(D3DMATRIX* m, float angle) {
    float sinA = sinf(angle);
    float cosA = cosf(angle);
    MatrixIdentity(m);
    m->_11 = cosA;  m->_31 = sinA;
    m->_13 = -sinA; m->_33 = cosA;
}

void MatrixTranslation(D3DMATRIX* m, float x, float y, float z) {
    MatrixIdentity(m);
    m->_41 = x;
    m->_42 = y;
    m->_43 = z;
}

void MatrixLookAtLH(D3DMATRIX* m, const float eye[3], const float at[3], const float up[3]) {
    float zaxis[3] = { at[0] - eye[0], at[1] - eye[1], at[2] - eye[2] };
    float len = sqrtf(zaxis[0] * zaxis[0] + zaxis[1] * zaxis[1] + zaxis[2] * zaxis[2]);
    zaxis[0] /= len; zaxis[1] /= len; zaxis[2] /= len;

    float xaxis[3];
    xaxis[0] = up[1] * zaxis[2] - up[2] * zaxis[1];
    xaxis[1] = up[2] * zaxis[0] - up[0] * zaxis[2];
    xaxis[2] = up[0] * zaxis[1] - up[1] * zaxis[0];
    len = sqrtf(xaxis[0] * xaxis[0] + xaxis[1] * xaxis[1] + xaxis[2] * xaxis[2]);
    xaxis[0] /= len; xaxis[1] /= len; xaxis[2] /= len;

    float yaxis[3];
    yaxis[0] = zaxis[1] * xaxis[2] - zaxis[2] * xaxis[1];
    yaxis[1] = zaxis[2] * xaxis[0] - zaxis[0] * xaxis[2];
    yaxis[2] = zaxis[0] * xaxis[1] - zaxis[1] * xaxis[0];

    MatrixIdentity(m);
    m->_11 = xaxis[0]; m->_12 = yaxis[0]; m->_13 = zaxis[0];
    m->_21 = xaxis[1]; m->_22 = yaxis[1]; m->_23 = zaxis[1];
    m->_31 = xaxis[2]; m->_32 = yaxis[2]; m->_33 = zaxis[2];
    m->_41 = -eye[0] * xaxis[0] - eye[1] * xaxis[1] - eye[2] * xaxis[2];
    m->_42 = -eye[0] * yaxis[0] - eye[1] * yaxis[1] - eye[2] * yaxis[2];
    m->_43 = -eye[0] * zaxis[0] - eye[1] * zaxis[1] - eye[2] * zaxis[2];
}

void MatrixPerspectiveFovLH(D3DMATRIX* m, float fov, float aspect, float znear, float zfar) {
    float yScale = 1.0f / tanf(fov / 2);
    float xScale = yScale / aspect;
    MatrixIdentity(m);
    m->_11 = xScale;
    m->_22 = yScale;
    m->_33 = zfar / (zfar - znear);
    m->_34 = 1.0f;
    m->_43 = -znear * zfar / (zfar - znear);
    m->_44 = 0.0f;
}

// 着色器代码
const char* vsCode =
"cbuffer ConstantBuffer : register(b0) {\n"
"    row_major float4x4 mWorld;\n"
"    row_major float4x4 mView;\n"
"    row_major float4x4 mProjection;\n"
"};\n"
"struct VS_OUTPUT {\n"
"    float4 pos : SV_POSITION;\n"
"    float4 color : COLOR;\n"
"};\n"
"VS_OUTPUT VS(float3 pos : POSITION, float4 color : COLOR) {\n"
"    VS_OUTPUT output;\n"
"    float4 pos4 = float4(pos, 1.0f);\n"
"    pos4 = mul(pos4, mul(mWorld, mul(mView, mProjection)));\n"
"    output.pos = pos4;\n"
"    output.color = color;\n"
"    return output;\n"
"}";

const char* psCode =
"struct PS_INPUT {\n"
"    float4 pos : SV_POSITION;\n"
"    float4 color : COLOR;\n"
"};\n"
"float4 PS(PS_INPUT input) : SV_TARGET {\n"
"    return input.color;\n"
"}";

// 初始化D3D设备
HRESULT InitD3D(HWND hWnd) {
    DXGI_SWAP_CHAIN_DESC sd = { 0 };
    sd.BufferCount = 1;
    sd.BufferDesc.Width = WIDTH;
    sd.BufferDesc.Height = HEIGHT;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hWnd;
    sd.SampleDesc.Count = 1;
    sd.Windowed = TRUE;

    D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
    HRESULT hr = D3D11CreateDeviceAndSwapChain(
        NULL,
        D3D_DRIVER_TYPE_HARDWARE,
        NULL,
        0,
        &featureLevel,
        1,
        D3D11_SDK_VERSION,
        &sd,
        &g_pSwapChain,
        &g_pDevice,
        NULL,
        &g_pContext
    );
    if (FAILED(hr)) return hr;

    // 获取BackBuffer
    ID3D11Texture2D* pBackBuffer = NULL;
    hr = g_pSwapChain->lpVtbl->GetBuffer(
        g_pSwapChain,
        0,
        &IID_ID3D11Texture2D,
        (void**)&pBackBuffer
    );
    if (FAILED(hr)) return hr;

    // 创建RenderTargetView
    hr = g_pDevice->lpVtbl->CreateRenderTargetView(
        g_pDevice,
        pBackBuffer,
        NULL,
        &g_pRenderTargetView
    );
    pBackBuffer->lpVtbl->Release(pBackBuffer);
    if (FAILED(hr)) return hr;

    // 创建深度模板纹理
    ID3D11Texture2D* pDepthStencil = NULL;
    D3D11_TEXTURE2D_DESC descDepth = { 0 };
    descDepth.Width = WIDTH;
    descDepth.Height = HEIGHT;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    descDepth.SampleDesc.Count = 1;
    descDepth.Usage = D3D11_USAGE_DEFAULT;
    descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    hr = g_pDevice->lpVtbl->CreateTexture2D(g_pDevice, &descDepth, NULL, &pDepthStencil);
    if (FAILED(hr)) return hr;

    // 创建深度模板视图
    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV = { 0 };
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    hr = g_pDevice->lpVtbl->CreateDepthStencilView(g_pDevice, pDepthStencil, &descDSV, &g_pDepthStencilView);
    pDepthStencil->lpVtbl->Release(pDepthStencil);
    if (FAILED(hr)) return hr;

    // 绑定RenderTarget和DepthStencil
    g_pContext->lpVtbl->OMSetRenderTargets(g_pContext, 1, &g_pRenderTargetView, g_pDepthStencilView);

    // 创建光栅化状态(禁用背面剔除)
    D3D11_RASTERIZER_DESC rsDesc = { 0 };
    rsDesc.FillMode = D3D11_FILL_SOLID;
    rsDesc.CullMode = D3D11_CULL_NONE; // 禁用剔除
    rsDesc.DepthClipEnable = TRUE;
    hr = g_pDevice->lpVtbl->CreateRasterizerState(g_pDevice, &rsDesc, &g_pRasterizerState);
    if (FAILED(hr)) return hr;

    // 设置光栅化状态
    g_pContext->lpVtbl->RSSetState(g_pContext, g_pRasterizerState);

    // 设置视口
    D3D11_VIEWPORT vp = { 0 };
    vp.Width = WIDTH;
    vp.Height = HEIGHT;
    vp.MaxDepth = 1.0f;
    g_pContext->lpVtbl->RSSetViewports(g_pContext, 1, &vp);

    return S_OK;
}

// 初始化图形资源
HRESULT InitGraphics() {
    // T80坦克顶点数据
    Vertex vertices[] = {
        // 车身(绿色)
        {{-2.0f,-0.5f,-1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{ 2.0f,-0.5f,-1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{ 2.0f, 0.5f,-1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{-2.0f, 0.5f,-1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{-2.0f,-0.5f, 1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{ 2.0f,-0.5f, 1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{ 2.0f, 0.5f, 1.0f}, {0.2f,0.5f,0.2f,1.0f}},
        {{-2.0f, 0.5f, 1.0f}, {0.2f,0.5f,0.2f,1.0f}},

        // 炮塔(深绿色)
        {{-0.8f, 0.5f,-0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{ 0.8f, 0.5f,-0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{ 0.8f, 1.2f,-0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{-0.8f, 1.2f,-0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{-0.8f, 0.5f, 0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{ 0.8f, 0.5f, 0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{ 0.8f, 1.2f, 0.8f}, {0.1f,0.3f,0.1f,1.0f}},
        {{-0.8f, 1.2f, 0.8f}, {0.1f,0.3f,0.1f,1.0f}},

        // 炮管(黑色)
        {{-0.2f, 1.0f,-1.5f}, {0.0f,0.0f,0.0f,1.0f}},
        {{ 0.2f, 1.0f,-1.5f}, {0.0f,0.0f,0.0f,1.0f}},
        {{ 0.2f, 1.0f, 2.0f}, {0.0f,0.0f,0.0f,1.0f}},
        {{-0.2f, 1.0f, 2.0f}, {0.0f,0.0f,0.0f,1.0f}},

        // 履带(灰色)
        {{-2.2f,-0.6f,-1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{ 2.2f,-0.6f,-1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{ 2.2f,-0.4f,-1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{-2.2f,-0.4f,-1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{-2.2f,-0.6f, 1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{ 2.2f,-0.6f, 1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{ 2.2f,-0.4f, 1.2f}, {0.3f,0.3f,0.3f,1.0f}},
        {{-2.2f,-0.4f, 1.2f}, {0.3f,0.3f,0.3f,1.0f}},
    };

    // 索引数据
    WORD indices[] = {
        // 车身
        0,1,2, 0,2,3, 4,5,6, 4,6,7,
        0,4,5, 0,5,1, 1,5,6, 1,6,2,
        2,6,7, 2,7,3, 3,7,4, 3,4,0,

        // 炮塔
        8,9,10, 8,10,11, 12,13,14, 12,14,15,
        8,12,13, 8,13,9, 9,13,14, 9,14,10,
        10,14,15, 10,15,11, 11,15,12, 11,12,8,

        // 炮管
        16,17,18, 16,18,19,
        16,19,18, 16,18,17,

        // 履带
        20,21,22, 20,22,23, 24,25,26, 24,26,27,
        20,24,25, 20,25,21, 21,25,26, 21,26,22,
        22,26,27, 22,27,23, 23,27,24, 23,24,20
    };

    // 创建顶点缓冲
    D3D11_BUFFER_DESC bd = { 0 };
    bd.ByteWidth = sizeof(vertices);
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;

    D3D11_SUBRESOURCE_DATA initData = { 0 };
    initData.pSysMem = vertices;

    HRESULT hr = g_pDevice->lpVtbl->CreateBuffer(
        g_pDevice,
        &bd,
        &initData,
        &g_pVertexBuffer
    );
    if (FAILED(hr)) return hr;

    // 创建索引缓冲
    bd.ByteWidth = sizeof(indices);
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    initData.pSysMem = indices;
    hr = g_pDevice->lpVtbl->CreateBuffer(
        g_pDevice,
        &bd,
        &initData,
        &g_pIndexBuffer
    );
    if (FAILED(hr)) return hr;

    // 编译着色器
    ID3DBlob* pVSBlob = NULL, * pPSBlob = NULL;
    hr = D3DCompile(
        vsCode, strlen(vsCode), NULL, NULL, NULL,
        "VS", "vs_4_0", 0, 0,
        &pVSBlob, NULL
    );
    if (SUCCEEDED(hr)) {
        hr = g_pDevice->lpVtbl->CreateVertexShader(
            g_pDevice,
            pVSBlob->lpVtbl->GetBufferPointer(pVSBlob),
            pVSBlob->lpVtbl->GetBufferSize(pVSBlob),
            NULL,
            &g_pVertexShader
        );
        if (SUCCEEDED(hr)) {
            D3D11_INPUT_ELEMENT_DESC layout[] = {
                {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
                {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
            };
            hr = g_pDevice->lpVtbl->CreateInputLayout(
                g_pDevice,
                layout,
                2,
                pVSBlob->lpVtbl->GetBufferPointer(pVSBlob),
                pVSBlob->lpVtbl->GetBufferSize(pVSBlob),
                &g_pInputLayout
            );
        }
        pVSBlob->lpVtbl->Release(pVSBlob);
    }
    if (FAILED(hr)) return hr;

    hr = D3DCompile(
        psCode, strlen(psCode), NULL, NULL, NULL,
        "PS", "ps_4_0", 0, 0,
        &pPSBlob, NULL
    );
    if (SUCCEEDED(hr)) {
        hr = g_pDevice->lpVtbl->CreatePixelShader(
            g_pDevice,
            pPSBlob->lpVtbl->GetBufferPointer(pPSBlob),
            pPSBlob->lpVtbl->GetBufferSize(pPSBlob),
            NULL,
            &g_pPixelShader
        );
        pPSBlob->lpVtbl->Release(pPSBlob);
    }
    if (FAILED(hr)) return hr;

    // 创建常量缓冲
    bd.ByteWidth = sizeof(ConstantBuffer);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    hr = g_pDevice->lpVtbl->CreateBuffer(
        g_pDevice,
        &bd,
        NULL,
        &g_pConstantBuffer
    );
    return hr;
}

// 渲染帧
void RenderFrame() {
    static float tankRotation = 0.0f;  // 车身旋转角度
    static float turretRotation = 0.0f; // 炮塔旋转角度
    tankRotation += 0.0005f;  // 车身缓慢旋转
    turretRotation += 0.001f; // 炮塔更快旋转

    // 更新矩阵
    ConstantBuffer cb;
    float eye[] = { 0,3,-5 }, at[] = { 0,0,0 }, up[] = { 0,1,0 };
    MatrixLookAtLH(&cb.mView, eye, at, up);
    MatrixPerspectiveFovLH(&cb.mProjection, 3.1415926f / 2, (float)WIDTH / HEIGHT, 0.01f, 100.0f);

    // 清屏和深度缓冲
    float clearColor[4] = { 0,0,0,1 };
    g_pContext->lpVtbl->ClearRenderTargetView(
        g_pContext,
        g_pRenderTargetView,
        clearColor
    );
    g_pContext->lpVtbl->ClearDepthStencilView(
        g_pContext,
        g_pDepthStencilView,
        D3D11_CLEAR_DEPTH,
        1.0f,
        0
    );

    // 设置渲染管线
    g_pContext->lpVtbl->VSSetShader(
        g_pContext,
        g_pVertexShader,
        NULL,
        0
    );
    g_pContext->lpVtbl->PSSetShader(
        g_pContext,
        g_pPixelShader,
        NULL,
        0
    );
    g_pContext->lpVtbl->VSSetConstantBuffers(
        g_pContext,
        0,
        1,
        &g_pConstantBuffer
    );
    g_pContext->lpVtbl->IASetInputLayout(
        g_pContext,
        g_pInputLayout
    );

    // 设置顶点缓冲
    UINT stride = sizeof(Vertex), offset = 0;
    g_pContext->lpVtbl->IASetVertexBuffers(
        g_pContext,
        0,
        1,
        &g_pVertexBuffer,
        &stride,
        &offset
    );
    g_pContext->lpVtbl->IASetIndexBuffer(
        g_pContext,
        g_pIndexBuffer,
        DXGI_FORMAT_R16_UINT,
        0
    );
    g_pContext->lpVtbl->IASetPrimitiveTopology(
        g_pContext,
        D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
    );

    // 绘制车身
    MatrixRotationY(&cb.mWorld, tankRotation);
    g_pContext->lpVtbl->UpdateSubresource(
        g_pContext,
        g_pConstantBuffer,
        0,
        NULL,
        &cb,
        0,
        0
    );
    g_pContext->lpVtbl->DrawIndexed(
        g_pContext,
        36, // 车身索引数
        0,
        0
    );
    // 绘制履带
    g_pContext->lpVtbl->DrawIndexed(
        g_pContext,
        36, // 履带索引数
        84, // 起始索引
        0
    );

    // 绘制炮塔
    D3DMATRIX turretWorld;
    MatrixRotationY(&turretWorld, turretRotation);
    cb.mWorld = turretWorld; // 炮塔独立旋转
    g_pContext->lpVtbl->UpdateSubresource(
        g_pContext,
        g_pConstantBuffer,
        0,
        NULL,
        &cb,
        0,
        0
    );
    g_pContext->lpVtbl->DrawIndexed(
        g_pContext,
        36, // 炮塔索引数
        36, // 起始索引
        0
    );

    // 绘制炮管
    g_pContext->lpVtbl->DrawIndexed(
        g_pContext,
        12, // 炮管索引数
        72, // 起始索引
        0
    );



    // 呈现
    g_pSwapChain->lpVtbl->Present(
        g_pSwapChain,
        0,
        0
    );
}

// 窗口过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (msg == WM_DESTROY) {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

// 主函数
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX),
        CS_HREDRAW | CS_VREDRAW,
        WndProc,
        0,
        0,
        hInst,
        NULL,
        NULL,
        (HBRUSH)(COLOR_WINDOW + 1),
        NULL,
        L"D3DWindow",
        NULL
    };
    RegisterClassEx(&wc);

    HWND hWnd = CreateWindow(
        wc.lpszClassName,
        L"T80坦克模型",
        WS_OVERLAPPEDWINDOW,
        100, 100, WIDTH, HEIGHT,
        NULL, NULL, hInst, NULL
    );

    if (SUCCEEDED(InitD3D(hWnd)) && SUCCEEDED(InitGraphics())) {
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);

        MSG msg = { 0 };
        while (msg.message != WM_QUIT) {
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else {
                RenderFrame();
            }
        }
    }

    // 释放资源
    if (g_pRasterizerState) g_pRasterizerState->lpVtbl->Release(g_pRasterizerState);
    if (g_pDepthStencilView) g_pDepthStencilView->lpVtbl->Release(g_pDepthStencilView);
    if (g_pRenderTargetView) g_pRenderTargetView->lpVtbl->Release(g_pRenderTargetView);
    if (g_pSwapChain) g_pSwapChain->lpVtbl->Release(g_pSwapChain);
    if (g_pContext) g_pContext->lpVtbl->Release(g_pContext);
    if (g_pDevice) g_pDevice->lpVtbl->Release(g_pDevice);

    return 0;
}
d3d11

 ### **步骤 1:创建新项目**
1. 打开Visual Studio → 选择 **“创建新项目”** 

2. 搜索并选择 **“空项目”** → 点击 **“下一步”** 

3. 输入项目名称(例如 `D3D11Cube`)→ 指定项目位置 → 点击 **“创建”** 

### **步骤 2:配置项目属性**
1. **右键项目 → 属性** 

2. **关键配置项**:
   - **配置**:`All Configurations`(确保Debug和Release都生效)
   - **平台**:`x64`(推荐,D3D11需要64位环境)

   | 配置项 | 设置值 |
   |---|---|
   | **C/C++ → 常规 → 附加包含目录** | `$(WindowsSDK_IncludePath)` |
   | **链接器 → 输入 → 附加依赖项** | `d3d11.lib;d3dcompiler.lib;dxguid.lib` |
   | **链接器 → 系统 → 子系统** | `Windows (/SUBSYSTEM:WINDOWS)` |
   | **C/C++ → 预处理器 → 预处理器定义** | `UNICODE;_UNICODE` |

### **步骤 3:添加源代码**
1. **右键源文件文件夹 → 添加 → 新建项** → 选择 **“C++文件”** 

2. 将之前的完整代码粘贴到新文件中(文件名例如 `main.c`)


### **步骤 4:修复代码依赖项**
1. **确保包含头文件**:
   ```c
   #include <windows.h>
   #include <d3d11.h>
   #include <d3dcompiler.h>

   ```

### **步骤 5:编译并运行**

 

posted on 2025-02-03 11:23  jacob1934  阅读(36)  评论(0)    收藏  举报

导航