渐变(tweening)网格模型是Direct3D中实现模型动画最简单的方式和途径,它的原理也非常简单。例如对于场景内的某个网格模型,最初只记录t0时刻和t1时刻该网格模型的状态(即这两个时刻网格模型中所有顶点的位置),对于t0到t1这段时间内的任意时刻t_current,根据该时刻距离t0和t1时刻的远近,实时地分配给这两个网格模型不同的权重,然后按照这两个网格模型中顶点的不同位置和它们各自的权重进行插值,计算出t_current时刻整个网格模型中所有顶点的位置,从而实现动画效果。

通常将t0时刻的网格模型称为源网格模型,将t1时刻的网格模型称为目标网格模型,将最后拟合得到的网格模型称为结果网格模型。当然初始条件还可以是3个或更多时刻网格模型的状态,再根据时间的推移对这些网格模型进行插值而实时得到当前时刻网格模型的状态。

事实上,渐变网格模型就是对一系列已知的网格模型进行插值得到最终的网格模型。

首先,我们需要从.x文件加载源网格模型和目标网格模型:

V_RETURN(D3DXLoadMeshFromXW(L"source.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials, &g_source_mesh));
V_RETURN(D3DXLoadMeshFromXW(L"target.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials, &g_target_mesh));

由于我们仅对两个网格模型中的顶点位置坐标和法向量进行插值,所以在创建好源网格模型和目标网格模型后,需要按照指定的顶点格式克隆源网格模型、目标网格模型和结果网格模型,使这时的源网格模型、目标网格模型和结果网格模型仅包含顶点位置和法向量:

ID3DXMesh* cloned_mesh;
// clone source mesh with specified vertex format
g_source_mesh->CloneMeshFVF(g_source_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &cloned_mesh);
release_com(g_source_mesh);
g_source_mesh = cloned_mesh;
// clone target mesh with specified vertex format
g_target_mesh->CloneMeshFVF(g_target_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &cloned_mesh);
release_com(g_target_mesh);
g_target_mesh = cloned_mesh;
// clone result mesh with specified vertex format from target mesh
g_target_mesh->CloneMeshFVF(g_target_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &g_result_mesh);
g_source_mesh->GetVertexBuffer(&g_source_vb);
g_target_mesh->GetVertexBuffer(&g_target_vb);
g_result_mesh->GetVertexBuffer(&g_result_vb);
 

其中源网格模型的状态如下图所示:

目标网格模型的状态如下图所示:

最后我们根据程序当前运行时间,分别计算源网格模型和目标网格模型的权重,利用计算出的权重对源网格模型和目标网格模型的顶点坐标和法向量进行插值,得到当前时刻的结果网格模型:

sVertex* source_vertices;
sVertex* target_vertices;
sVertex* result_vertices;
g_source_vb->Lock(0, 0, (void**) &source_vertices, 0);
g_target_vb->Lock(0, 0, (void**) &target_vertices, 0);
g_result_vb->Lock(0, 0, (void**) &result_vertices, 0);
float time_factor = (float)(timeGetTime() % 2000) / 1000.0f;
float scalar      = (time_factor <= 1.0f) ? time_factor : (2.0f - time_factor);
for(DWORD i = 0; i < g_result_mesh->GetNumVertices(); i++)
{result_vertices[i].x = source_vertices[i].x * (1.0f - scalar) + target_vertices[i].x * scalar;result_vertices[i].y = source_vertices[i].y * (1.0f - scalar) + target_vertices[i].y * scalar;result_vertices[i].z = source_vertices[i].z * (1.0f - scalar) + target_vertices[i].z * scalar;
   result_vertices[i].nx = source_vertices[i].nx * (1.0f - scalar) + target_vertices[i].nx * scalar;result_vertices[i].ny = source_vertices[i].ny * (1.0f - scalar) + target_vertices[i].ny * scalar;result_vertices[i].nz = source_vertices[i].nz * (1.0f - scalar) + target_vertices[i].nz * scalar;
}
g_source_vb->Unlock();
g_target_vb->Unlock();
g_result_vb->Unlock();

为了让海豚动起来,我们还必须修改世界坐标矩阵:

// move dolphin around circle
float kick_freq = float(2.0f * fTime);
float phas       = float(fTime) / 3.0f;
D3DXMATRIX mat_dolphin, mat_trans, mat_rot_y, mat_rot_z;
D3DXMatrixScaling(&mat_dolphin, 0.01f, 0.01f, 0.01f);
D3DXMatrixRotationZ(&mat_rot_z, -cosf(kick_freq) / 6);
D3DXMatrixRotationY(&mat_rot_y, phase);
D3DXMatrixTranslation(&mat_trans, -5 * sinf(phase), sinf(kick_freq)/2, 10 - 10 * cosf(phase));
mat_dolphin = mat_dolphin * mat_rot_z * mat_rot_y * mat_trans;;
pd3dDevice->SetTransform(D3DTS_WORLD, &mat_dolphin);

运行效果图:

主程序:

#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

struct sVertex
{
    float x, y, z;
    float nx, ny, nz;
};

const DWORD CUSTOM_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL;

#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;

ID3DXMesh*                    g_source_mesh;
ID3DXMesh*                    g_target_mesh;
ID3DXMesh*                    g_result_mesh;

IDirect3DVertexBuffer9*        g_source_vb;
IDirect3DVertexBuffer9*        g_target_vb;
IDirect3DVertexBuffer9*        g_result_vb;

DWORD                        g_num_materials;

//--------------------------------------------------------------------------------------
// 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);
}

//--------------------------------------------------------------------------------------
// 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, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
                   DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_font);

V_RETURN(D3DXLoadMeshFromXW(L"source.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials,
                                &g_source_mesh));

V_RETURN(D3DXLoadMeshFromXW(L"target.x", D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, &g_num_materials,
                                &g_target_mesh));

ID3DXMesh* cloned_mesh;

// clone source mesh with specified vertex format
    g_source_mesh->CloneMeshFVF(g_source_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &cloned_mesh);
    release_com(g_source_mesh);
    g_source_mesh = cloned_mesh;

// clone target mesh with specified vertex format
    g_target_mesh->CloneMeshFVF(g_target_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &cloned_mesh);
    release_com(g_target_mesh);
    g_target_mesh = cloned_mesh;

// clone result mesh with specified vertex format from target mesh
    g_target_mesh->CloneMeshFVF(g_target_mesh->GetOptions(), CUSTOM_VERTEX_FVF, pd3dDevice, &g_result_mesh);

g_source_mesh->GetVertexBuffer(&g_source_vb);
    g_target_mesh->GetVertexBuffer(&g_target_vb);
    g_result_mesh->GetVertexBuffer(&g_result_vb);

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 - 170, 0);
    g_button_dlg.SetSize(170, 170);

// setup view matrix

D3DXMATRIX mat_view;
    D3DXVECTOR3 eye(0.0f, 0.0f,  -8.0f);
    D3DXVECTOR3  at(0.0f, 0.0f,  0.0f);
    D3DXVECTOR3  up(0.0f, 1.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.0f, 100.0f);
    pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_proj);

// setup material

D3DMATERIAL9 material;
    ZeroMemory(&material, sizeof(D3DMATERIAL9));

material.Diffuse.r = 0.5f;
    material.Diffuse.g = 0.5f;
    material.Diffuse.b = 0.8f;
    material.Diffuse.a = 1.0f;

material.Ambient.r = 0.5f;
    material.Ambient.g = 0.5f;
    material.Ambient.b = 0.8f;
    material.Ambient.a = 1.0f;

pd3dDevice->SetMaterial(&material);

// setup light

D3DLIGHT9 light;
    ZeroMemory(&light, sizeof(D3DLIGHT9));

light.Type       = D3DLIGHT_DIRECTIONAL;

light.Diffuse.r  = 0.1f;
    light.Diffuse.g  = 0.1f;
    light.Diffuse.b  = 0.3f;
    light.Diffuse.a  = 1.0f;

light.Ambient.r  = 0.1f;
    light.Ambient.g  = 0.1f;
    light.Ambient.b  = 0.3f;
    light.Ambient.a  = 1.0f;

D3DXVECTOR3 light_dir = D3DXVECTOR3(-1, -1, 1);
    D3DXVec3Normalize((D3DXVECTOR3*) &light.Direction, &light_dir);
    pd3dDevice->SetLight(0, &light);
    pd3dDevice->LightEnable(0, TRUE);
    pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

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();

release_com(g_font);

release_com(g_source_mesh);
    release_com(g_target_mesh);   
    release_com(g_result_mesh);

release_com(g_source_vb);
    release_com(g_target_vb);
    release_com(g_result_vb);
}

//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    sVertex* source_vertices;
    sVertex* target_vertices;
    sVertex* result_vertices;

g_source_vb->Lock(0, 0, (void**) &source_vertices, 0);
    g_target_vb->Lock(0, 0, (void**) &target_vertices, 0);
    g_result_vb->Lock(0, 0, (void**) &result_vertices, 0);

float time_factor = (float)(timeGetTime() % 2000) / 1000.0f;
    float scalar      = (time_factor <= 1.0f) ? time_factor : (2.0f - time_factor);

for(DWORD i = 0; i < g_result_mesh->GetNumVertices(); i++)
    {
        result_vertices[i].x = source_vertices[i].x * (1.0f - scalar) + target_vertices[i].x * scalar;
        result_vertices[i].y = source_vertices[i].y * (1.0f - scalar) + target_vertices[i].y * scalar;
        result_vertices[i].z = source_vertices[i].z * (1.0f - scalar) + target_vertices[i].z * scalar;

result_vertices[i].nx = source_vertices[i].nx * (1.0f - scalar) + target_vertices[i].nx * scalar;
        result_vertices[i].ny = source_vertices[i].ny * (1.0f - scalar) + target_vertices[i].ny * scalar;
        result_vertices[i].nz = source_vertices[i].nz * (1.0f - scalar) + target_vertices[i].nz * scalar;
    }

g_source_vb->Unlock();
    g_target_vb->Unlock();
    g_result_vb->Unlock();

// move dolphin around circle

float kick_freq = float(2.0f * fTime);
    float phase        = float(fTime) / 3.0f;

D3DXMATRIX mat_dolphin, mat_trans, mat_rot_y, mat_rot_z;

D3DXMatrixScaling(&mat_dolphin, 0.01f, 0.01f, 0.01f);
    D3DXMatrixRotationZ(&mat_rot_z, -cosf(kick_freq) / 6);
    D3DXMatrixRotationY(&mat_rot_y, phase);
    D3DXMatrixTranslation(&mat_trans, -5 * sinf(phase), sinf(kick_freq)/2, 10 - 10 * cosf(phase));

mat_dolphin = mat_dolphin * mat_rot_z * mat_rot_y * mat_trans;;

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

//--------------------------------------------------------------------------------------
// 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(5, 5);
    text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
    text_helper.DrawTextLine( DXUTGetFrameStats(true) );
    text_helper.DrawTextLine( DXUTGetDeviceStats() );

// 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.0f, 0.475f, 0.0f, 1.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.0f, 1.0f, 1.0f, 1.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(0, 32, 64, 128), 1.0f, 0) );

// Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        for(DWORD i = 0; i < g_num_materials; i++)
            g_result_mesh->DrawSubset(i);

RenderText();
        V(g_button_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;
   
    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 event, int 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;
    }
}

//--------------------------------------------------------------------------------------
// Initialize dialogs
//--------------------------------------------------------------------------------------
void InitDialogs()
{
    g_settings_dlg.Init(&g_dlg_resource_manager);
    g_button_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);
}

//--------------------------------------------------------------------------------------
// 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( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"Tweening" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );

// Start the render loop
    DXUTMainLoop();

// TODO: Perform any application-level cleanup here

return DXUTGetExitCode();
}

下载示例工程

网格模型高级技术(8)相关推荐

  1. r语言 计算模型的rmse_直播丨R语言与作物模型高级应用实战技术应用

    随着基于过程的作物生长模型(Process-based Crop Growth Simulation Model)的发展,R语言在作物生长模型和数据分析.挖掘和可视化中发挥着越来越重要的作用.想要成为 ...

  2. 基于R语言的代理模型(高斯过程、贝叶斯优化、敏感性分析、异方差性等)高级技术应用

    基于R语言的代理模型(高斯过程.贝叶斯优化.敏感性分析.异方差性等)高级技术应用 直播时间:10月30日-10月31日.11月6日-7日(4天+1周辅导练习) (上午9:30-12:00  下午14: ...

  3. GridView 高级技术

    GridView 高级技术 汇总脚注 GridView 的主要目标是显示一组记录,但是你还可以加入一些有趣的信息,如汇总数据.需要如下的操作: 设置 GridView.ShowFooter 为 tru ...

  4. D3D中网格模型的运用

    在最底层的层次中,Direct3D并不使用网格模型,而只是使用多边形.D3DX增强了 Direct3D系统的功能性,添加了一系列负责处理网格模型的容器和进行渲染的对象..X文件是微软公司所开发的,高度 ...

  5. [译]基于GPU的体渲染高级技术之raycasting算法

    [译]基于GPU的体渲染高级技术之raycasting算法 PS:我决定翻译一下<Advanced Illumination Techniques for GPU-Based Volume Ra ...

  6. spring(7)spring mvc 的高级技术

    [0]README 1)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review  "spring(7)spring mvc 的高级技术 ...

  7. 如何准备Java初级和高级技术的面试呢?

    IT行业的崛起带动了一大批的新兴职业,Java数据开发就是其中之一,作为IT行业的刚需职位,企业对合格的Java开发人员求贤若渴, 在各大主流招聘平台上, Java相关职位数量一直名列前茅,那么我们如 ...

  8. 6 篇 2019 年最新模型剪枝技术合集

    点击我爱计算机视觉标星,更快获取CVML新技术 本文转载自机器之心. 选自heartbeat.fritz.ai 作者:Derrick Mwiti 机器之心编译 参与:魔王.蛋酱 对于剪枝技术,你了解多 ...

  9. autosar架构详细介绍_基于MATLAB环境搭建满足AUTOSAR标准的模型高级培训班

    一.课程目标 1.加深对AUTOSAR标准的认识和理解 2.能够在MATLAB平台上搭建满足AUTOSAR标准要求的应用层软件模型 3.掌握建模过程中的关键概念并能够灵活运用 4.掌握一些高级建模技巧 ...

最新文章

  1. 登上Science子刊,神经科学再次启发DNN设计!中科院揭秘介观自组织反向传播机制...
  2. java导出pdf字体宋体不加粗_docx4j word转pdf 中文宋体(中文正文)类型转换乱码...
  3. 脚本自动实现DNS服务各区域配置文件
  4. linux之pmap命令
  5. 【机器视觉】 fuzzy_measure_pairs算子
  6. 7.Handling Missing Values
  7. linux kvm图标需要安装的软件,KVM 图形化安装
  8. 代码阅读软件kscope源码安装指导
  9. LeetCode OJ:Bitwise AND of Numbers Range
  10. 使用Simscape搭建车辆仿真模块
  11. Ubuntu使用ZTE MF832S上网卡拨号上网
  12. Spring data elasticsearch添加同义词组件实现同义词热更新
  13. linux设置合上电脑,CentOS7设置笔记本合盖不休眠
  14. keras实现交叉验证以及K折交叉验证
  15. JAVA图形小动画之简单行星运动
  16. [转载]Qt涂鸦板程序图文详细教程..Qt涂鸦板程序图文详
  17. 爬取今日头条收藏夹文章列表信息
  18. 全基因组关联分析GWAS专题2——连锁不平衡
  19. qiime2-2022.8基于ubuntu的安装教程
  20. 群联PS3111+7DDL+JMS578转接板,开卡pSLC,附PS3111量产工具

热门文章

  1. awx文件解析_9awx.com
  2. 织物缝纫的一些知识总结
  3. 从头开始学51单片机之6:定时器/计数器
  4. vue 的双向绑定原理
  5. linux expect 读取文件循环,linux expect的使用详解,实例
  6. 医疗平台,专攻医学软件方向,病历云、影像学、实验室检验
  7. cocos2dx以前的一些文章的项目下载地址
  8. PACS/RIS影像管理系统源码,采用VC++编程语言,提供三维图像后处理和算法
  9. 用java编写输出欢迎光临_编写一个完整的Java applet程序,程序功能为:在屏幕上输出“欢迎光临Java世界!”的字符串信息。...
  10. sql 查询 aeiou元素