python d3d_D3D中的拾取 - 天行健 君子当自强而不息 - C++博客

#include "d3dUtility.h"

#pragma warning(disable : 4100)constintWIDTH  = 640;constintHEIGHT = 480;

IDirect3DDevice9*    g_device;

ID3DXMesh*            g_teapot;

ID3DXMesh*            g_sphere;

D3DXMATRIX            g_world_matrix;

cBoundingSphere        g_bounding_sphere;sRay calculate_picking_ray(intx,inty)

{

D3DVIEWPORT9 viewport;

g_device->GetViewport(&viewport);

D3DXMATRIX proj_matrix;

g_device->GetTransform(D3DTS_PROJECTION, &proj_matrix);floatpx = ((( 2.0f * x) / viewport.Width)  - 1.0f) / proj_matrix(0, 0);floatpy = (((-2.0f * y) / viewport.Height) + 1.0f) / proj_matrix(1, 1);

sRay ray;

ray.origin      = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

ray.direction = D3DXVECTOR3(px, py, 1.0f);returnray;

}voidtransform_ray(sRay* ray, D3DXMATRIX* trans_matrix)

{// transform the ray's origin, w = 1.D3DXVec3TransformCoord(&ray->origin, &ray->origin, trans_matrix);// transform the ray's direction, w = 0.D3DXVec3TransformNormal(&ray->direction, &ray->direction, trans_matrix);// normalize the directionD3DXVec3Normalize(&ray->direction, &ray->direction);

}boolray_sphere_intersect(sRay* ray, cBoundingSphere* sphere)

{

D3DXVECTOR3 v = ray->origin - sphere->m_center;floatb = 2.0f * D3DXVec3Dot(&ray->direction, &v);floatc = D3DXVec3Dot(&v, &v) - (sphere->m_radius * sphere->m_radius);floatdiscriminant = (b * b) - (4.0f * c);if(discriminant 

discriminant = sqrt(discriminant);floats0 = (-b + discriminant) / 2.0f;floats1 = (-b - discriminant) / 2.0f;// if one solution is >= 0, then we intersected the sphere.return(s0 >= 0.0f || s1 >= 0.0f);

}boolsetup()

{

D3DXCreateTeapot(g_device, &g_teapot, NULL);// compute the bounding sphereBYTE* v;

g_teapot->LockVertexBuffer(0, (void**)&v);

D3DXComputeBoundingSphere(

(D3DXVECTOR3*)v,

g_teapot->GetNumVertices(),

D3DXGetFVFVertexSize(g_teapot->GetFVF()),

&g_bounding_sphere.m_center,

&g_bounding_sphere.m_radius);

g_teapot->UnlockVertexBuffer();// build a sphere mesh that describes the teapot's bounding sphereD3DXCreateSphere(g_device, g_bounding_sphere.m_radius, 20, 20, &g_sphere, NULL);// set lightD3DXVECTOR3 dir(0.707f, -0.0f, 0.707f);

D3DXCOLOR color(1.0f, 1.0f, 1.0f, 1.0f);

D3DLIGHT9 light = init_directional_light(&dir, &color);

g_device->SetLight(0, &light);

g_device->LightEnable(0, TRUE);

g_device->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);

g_device->SetRenderState(D3DRS_SPECULARENABLE,   FALSE);// Set view matrixD3DXVECTOR3 pos(0.0f, 0.0f, -10.0f);

D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);

D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

D3DXMATRIX view_matrix;

D3DXMatrixLookAtLH(&view_matrix, &pos, &target, &up);

g_device->SetTransform(D3DTS_VIEW, &view_matrix);// set the projection matrixD3DXMATRIX proj;

D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI/4.0f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);

g_device->SetTransform(D3DTS_PROJECTION, &proj);returntrue;

}///voidcleanup()

{

safe_release(g_teapot);

safe_release(g_sphere);

}///booldisplay(floattime_delta)

{// update teapotstaticfloatradius = 0.0f;staticfloatangle  = 0.0f;

D3DXMatrixTranslation(&g_world_matrix, cos(angle) * radius, sin(angle) * radius, 10.0f);// transform the bounding sphere to match the teapot's position in the worldg_bounding_sphere.m_center = D3DXVECTOR3(cos(angle) * radius, sin(angle) * radius, 10.0f);staticfloatvelocity = 1.0f;

radius += velocity * time_delta;if(radius >= 8.0f || radius <= 0.0f)

velocity = -velocity;// reverse directionangle += D3DX_PI * time_delta;if(angle >= D3DX_PI * 2.0f)

angle = 0.0f;// render nowg_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);

g_device->BeginScene();

g_device->SetTransform(D3DTS_WORLD, &g_world_matrix);

g_device->SetMaterial(&RED_MATERIAL);

g_teapot->DrawSubset(0);// render the bounding sphere with alpha blending so we can see through itg_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

g_device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);

g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

D3DMATERIAL9 yellow_material = YELLOW_MATERIAL;

yellow_material.Diffuse.a = 0.25f;// 25% opacityg_device->SetMaterial(&yellow_material);

g_sphere->DrawSubset(0);

g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

g_device->EndScene();

g_device->Present(NULL, NULL, NULL, NULL);returntrue;

}///LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)

{switch(msg)

{caseWM_DESTROY:

PostQuitMessage(0);break;caseWM_KEYDOWN:if(word_param == VK_ESCAPE)

DestroyWindow(hwnd);break;caseWM_LBUTTONDOWN:// compute the ray in view space given by the clicked screen pointsRay ray = calculate_picking_ray(LOWORD(long_param), HIWORD(long_param));// transform the ray to world spaceD3DXMATRIX view_matrix, view_inverse_matrix;

g_device->GetTransform(D3DTS_VIEW, &view_matrix);

D3DXMatrixInverse(&view_inverse_matrix, NULL, &view_matrix);

transform_ray(&ray, &view_inverse_matrix);if(ray_sphere_intersect(&ray, &g_bounding_sphere))

MessageBox(NULL, "Hit teapot's bounding sphere!", "HIT", MB_OK);break;

}returnDefWindowProc(hwnd, msg, word_param, long_param);

}///intWINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line,intcmd_show)

{if(! init_d3d(inst, WIDTH, HEIGHT,true, D3DDEVTYPE_HAL, &g_device))

{

MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);return0;

}if(! setup())

{

MessageBox(NULL, "Steup() - failed.", 0, MB_OK);return0;

}

enter_msg_loop(display);

cleanup();

g_device->Release();return0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值