beautiful graphics, beautiful world!
#
下面开始描述我是怎么样去实现方法五的。
根据我目前掌握的知识,和实验室已知的编程条件,方法五我需要以下三个过程:
(1) 在CGAL框架下生成GPU的绘制数据。
对原Mesh的每个面生成局部坐标系;
由局部坐标系形成面的OBB包围盒Shell;
Shell划分为5个Tetrahedron;
根据离散化规格沿Z轴产生等距的Slice,每个Slice与Tetrahedron产生的交点即为GPU的输入顶点数据流。
Cylinder内部看
(2) GPU绘制
根据得到的顶点数据流,以及距离计算函数对每个切片数据进行绘制。绘制的过程其实一直都是有问题的,个中的原因我也说不清楚,只是知道结果是不正确的。
直到这个图才有了点成功的迹象~
对深度计算方法进行调整好以后才出现了自己想要的结果。以下是三个连续的切片。从整体上来看数据还是好的,但是最遗憾的就是中间的黑色部分出现了间断。
由于vtk处理的数据是8或24位的,而D3D的函数默认生成bmp图是32位的。这里幸亏张大帮忙,并提醒我用opencv来解决。Opencv不错,用起来挺方便的,建议数字图像处理的人用。
生成的64x64的8位灰度图如下:
(3) VTK根据切片数据,由2D的bmp图片生成3D网格模型
上图为GPU的绘制结果,通过vtk(Visualization Toolkit)绘制的结果。
vtkBMPReader *reader = vtkBMPReader::New(); reader->SetFilePrefix("D://cylinder/");
reader->SetFilePattern("%s%d.bmp");
reader->SetDataByteOrderToLittleEndian();
reader->SetDataSpacing(1, 1, 3);
reader->SetFileNameSliceSpacing(1);
reader->SetDataExtent(0, 63, 0, 63, 1, 50);
reader->Allow8BitBMPOn();
reader->Update();
生成了STL文件格式,然后再使用3ds Max进行obj文件格式转换。
比较郁闷的是网格模型竟然是双层的,不知道是什么原因啊?还好我的Deformation框架可以把文件读进来啊。
到现在,我的工作也可以说是到了一个段落了。接下来怎么改?迷茫~~
posted @ 2010-01-29 11:34 koilin 阅读(553) | 评论 (0) | 编辑 收藏
posted @ 2009-10-13 15:13 koilin 阅读(230) | 评论 (0) | 编辑 收藏
Visual Assist 添加支持*.cu文件1. 打开注册表,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Languages\File Extensions\ 下面添加子键 .cu 然后copy .cpp的键值到.cu。这样才能表示cu也是VS下的VC的工程文件。
2. 打开注册表HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\VANet8 在ExtSource键添加键值.cu。
3. 打开Visual Assist属性,在projects 的C/C++ Directories custom下面添加CUDA的头文件目录,这样才能在Visual Assist 生成规则的时候找到CUDA自身的特殊定义才能生成Visual Assist的关键字,如__global__.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/OpenHero/archive/2008/04/24/2324711.aspx
posted @ 2009-09-28 12:04 koilin 阅读(414) | 评论 (0) | 编辑 收藏
posted @ 2009-09-28 12:02 koilin 阅读(368) | 评论 (1) | 编辑 收藏
转自:http://memecha24.blog.163.com/blog/static/118137909200942494851483/环境反射效果
环境反射效果
就我所知常用的环境贴图有两种,一种是球状的环境贴图;一种是立方体的环境贴图。如果是制作水体的反射或折射效果也可以只做平面的环境贴图。
DirectX中提供了一个很方便的立方体环境贴图。立方体的六个面定义如下:
{
D3DCUBEMAP_FACE_POSITIVE_X = 0,
D3DCUBEMAP_FACE_NEGATIVE_X = 1,
D3DCUBEMAP_FACE_POSITIVE_Y = 2,
D3DCUBEMAP_FACE_NEGATIVE_Y = 3,
D3DCUBEMAP_FACE_POSITIVE_Z = 4,
D3DCUBEMAP_FACE_NEGATIVE_Z = 5,
D3DCUBEMAP_FACE_FORCE_DWORD = 0x7fffffff
} D3DCUBEMAP_FACES;
如下图所示:
实现原理也很简单:
1、把立方体环境贴图放到反射物体所知位置,并把该反射物体以外的东西映射到立方体环境贴图上。
2、根据摄像机到反射物体表面的点的向量a和该点的法向量n,求出a的反射向量b。
3、以反射向量b作为立方体环境贴图的寻址,把它所对应的颜色赋给反射物体上的点。
实现过程需要用到一个立方体环境贴图和一个深度表面,步骤如下:
LPDIRECT3DCUBETEXTURE9 m_pReflectCubeTex; //反射的立方贴图
LPDIRECT3DSURFACE9 m_pSurfDepthCube; // DepthStencilSurface
2、初始化
HRESULT hr;
//创建 DepthStencilSurface
DXUTDeviceSettings d3dSettings = DXUTGetDeviceSettings();
hr = pDev->CreateDepthStencilSurface( ENVMAPSIZE,
ENVMAPSIZE,
d3dSettings.pp.AutoDepthStencilFormat,
D3DMULTISAMPLE_NONE,
0,
TRUE,
& m_pSurfDepthCube,
NULL );
if( FAILED( hr))
return hr;
//创建立方体贴图
hr = pDev->CreateCubeTexture( ENVMAPSIZE,
1,
D3DUSAGE_RENDERTARGET,
D3DFMT_A16B16G16R16F,
D3DPOOL_DEFAULT,
& m_pReflectCubeTex,
if( FAILED( hr) )
3、把被反射物体渲染到立方体环境贴图中
//------------------------------------------------------------
//desc: 渲染反射场景
//param: pDev 设备
//return: 是否创建成功
HRESULT GRenderMaterialProxy::RenderReflectScene(LPDIRECT3DDEVICE9 pDev)
if( pDev == NULL)
return E_FAIL;
LPDIRECT3DSURFACE9 pSufRTBackup; //RenderTarget 备份
LPDIRECT3DSURFACE9 pSufDSBackup; //DepthStencilSurface 备份
pDev->GetRenderTarget( 0, & pSufRTBackup);
if( SUCCEEDED( pDev->GetDepthStencilSurface( & pSufDSBackup) ) )
pDev->SetDepthStencilSurface( m_pSurfDepthCube);
}
//以反射物体为中心,设置视口投影矩阵
LPDIRECT3DSURFACE9 pSurf;
D3DXMATRIXA16 mView, mProj;
D3DXMATRIXA16 mViewDir( * GCameraManager::GetInstance()->GetCamera()->GetViewMatrix() );
mViewDir._41 = mViewDir._42 = mViewDir._43 = 0.0f;
D3DXMatrixPerspectiveFovLH( &mProj, D3DX_PI * 0.5f, 1.0f, 0.01f, 10000.0f );
std::vector< IRenderObject *>::iterator itRenderObj;
//渲染Cube 6个表面
for( int iFace = 0; iFace < 6; ++iFace)
//获取立方体环境贴图表面,并设为设备的渲染目标
//注意:GetCubeMapSurface的第二个参数0表示获取立方体环境贴图的表面
//如果是 n则表示获取立方体环境贴图的第n层表面
V( m_pReflectCubeTex->GetCubeMapSurface( ( D3DCUBEMAP_FACES) iFace, 0, & pSurf));
V( pDev->SetRenderTarget( 0, pSurf));
mView = DXUTGetCubeMapViewMatrix( iFace);
D3DXMatrixMultiply( & mView, & mViewDir, & mView);
V( pDev->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0L ));
//渲染被反射物体
for( itRenderObj = m_vpReflectObjects.begin(); itRenderObj != m_vpReflectObjects.end(); itRenderObj++)
(*itRenderObj)->Render( pDev, & mView, & mProj);
SAFE_RELEASE( pSurf);
if( pSufDSBackup)
pDev->SetDepthStencilSurface( pSufDSBackup); //恢复深度表面
SAFE_RELEASE( pSufDSBackup);
pDev->SetRenderTarget( 0, pSufRTBackup); //恢复渲染目标
SAFE_RELEASE( pSufRTBackup);
return S_OK;
4、根据立方体环境贴图确定反射物体的颜色(用HLSL实现)
//渲染环境贴图
if( m_bEnableReflect)
RenderReflectScene( pDev);
D3DXMATRIXA16 mWorld, mView, mProj, mWorldView;
CBaseCamera * pCamera = GCameraManager::GetInstance()->GetCamera();
D3DXVECTOR4 vEyePos = D3DXVECTOR4(* GCameraManager::GetInstance()->GetCamera()->GetEyePt(), 0.0f);
D3DXMATRIXA16 mEyePos;
::D3DXMatrixTranslation( & mEyePos, vEyePos.x, vEyePos.y, vEyePos.z);
::D3DXMatrixTranslation( & mWorld, 0.0f, 0.0f, 0.0f);
mView = * pCamera->GetViewMatrix();
mProj = * pCamera->GetProjMatrix();
GVector4 * pLightDirList = G3DSceneManager::GetInstance()->GetLightDirList();
UINT iLightCount = G3DSceneManager::GetInstance()->GetLightCount();
//设置变化矩阵
m_pEffect->SetMatrix("g_mWorld", &mWorld);
m_pEffect->SetMatrix("g_mProj", &mProj);
m_pEffect->SetMatrix("g_mView", &mView);
m_pEffect->SetTexture("g_texReflect", m_pReflectCubeTex); //设置立方体环境贴图
m_pEffect->SetFloat("g_fReflectivity", m_fReflectivity); //设置反射率
( fx文件代码如下)
extern matrix g_mWorld;
extern matrix g_mView;
extern matrix g_mProj;
texture g_texReflect;
float g_fReflectivity = 0.9f;
samplerCUBE g_samReflect =
sampler_state
Texture = <g_texReflect>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};
void VS_Reflect( float4 iPos : POSITION,
float3 iNor : NORMAL,
out float4 oPos : POSITION,
out float3 oEnvTex : TEXCOORD0 )
matrix mWorldView = mul( g_mWorld, g_mView);
oPos = mul( iPos, mWorldView);
float3 vN = mul( iNor, mWorldView);
vN = normalize( vN);
float3 vEyeR = -normalize( oPos);
float3 vRef;
vRef = 2 * dot( vEyeR, vN) * vN - vEyeR;
//vRef = reflect( vEyeR, vN);
oEnvTex = vRef;
oPos = mul( oPos, g_mProj);
float4 PS_Reflect( float3 iTex : TEXCOORD0 ) : COLOR
float4 fColor = texCUBE( g_samReflect, iTex);
fColor.x = fColor.x * g_fReflectivity;
fColor.y = fColor.y * g_fReflectivity;
fColor.z = fColor.z * g_fReflectivity;
return fColor;
technique Tec_RenderMaterial
pass p0
vertexShader = compile vs_2_0 VS_Reflect();
pixelShader = compile ps_2_0 PS_Reflect();
实现效果如下:
posted @ 2009-09-28 10:27 koilin 阅读(886) | 评论 (0) | 编辑 收藏
1、D3DXMatrixPerspectiveFovLH()DirectX中投影变换D3DXMatrixPerspectiveFovLH()其实产生的变换矩阵不是将3D物体转换为2D平面画面的变换。实际上是把3D世界的物体变换到(1,1,0) (-1,1,0) (-1,-1,0) (1,-1,0) (1,1,1) (-1,1,1) (-1,-1,1) (1,-1,1)这个小盒子中。在Jim Adams 的著作<Role playing games with DriectX 8.0>和Frank Luna 的著作中<Introduction to 3D Game Programming with DirectX9.0>都把这个变换矩阵讲成从3D到2D的变换。实际上在DirectX中3D到2D的变换是由SDK自己完成的。而我们要做的是把3D世界变换到上面那个小盒子中。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/normallife/archive/2008/12/24/3597214.aspx2、LPDIRECT3DSURFACE9多重贴图其实就是先按照基本帖图方法为模型指定帖图,然后读入第二个帖图调用D3DXLoadSurfaceFromSurface(...)把第二个的部分贴到第一上.只是D3DXLoadSurfaceFromSurface()函数不能直接操作已经读入帖图文件定向到设备上的纹理对象Surfaces是什么:
通俗的讲surfaces就是一个二维的矩形平面。在DX9中,与其对应的com接口为IDirect3DSurface9,LPDIRECT3DSURFACE9。Surfaces的作用:
作为一个矩形平面,surfaces用来在屏幕上显示平面图象,即从文件中读取图象数据呈现给用户IDirect3DSurface9的使用一般过程:
声明: LPDIRECT3DSURFACE9
创建: CreateOffscreenPlainSurface(…)
获取图象信息: D3DXGetImageInfoFromFile(…)
装载到surfaces中: D3DXLoadSurfaceFromFile(…)
获取back buffer地址: GetBackBuffer(…)
显示: UpdateSurface(…)
释放内存 Release()3、GetRenderTarget()将对象渲染到指定目标上4、GetDepthStencilSurface
以下示例代码显示了如何使用IDirect3DDevice9::GetDepthStencilSurface方法取得设备拥有的深度缓存。
LPDIRECT3DSURFACE9 pZBuffer;5、 g_pEffect->CommitChanges()
对用通道中的状态设置,通过CommitChanges()更新变换,6、
m_d3dDevice->GetDepthStencilSurface( &pZBuffer );
posted @ 2009-09-26 10:57 koilin 阅读(648) | 评论 (0) | 编辑 收藏
突然才发现3dsMax竟然不能到处X模型,装了3D模型转换器也没有成功,磨去了一个下午~~现在终于解决了http://www.andytather.co.uk/Panda/directxmax.aspx上面下载panda exporter,是个DLE文件,然后放在3dsMax的安装路径下plugins文件夹下,之后在3dsMax的模型导出里面就可以选择.x模型了。
posted @ 2009-09-25 19:40 koilin 阅读(940) | 评论 (0) | 编辑 收藏
纹理坐标,其u和v值都在0~1之间,然而,如果我们给了一个超出范围的值怎么办呢?在DirectX和OpenGL中,早已为我们想到了这个问题。在DirectX中,有一种叫做Texture Addressing Mode的东西(在OpenGL中有Wraping Mode),提供了几种常见的方式:typedef enum D3DTEXTUREADDRESS{D3DTADDRESS_WRAP = 1,D3DTADDRESS_MIRROR = 2,D3DTADDRESS_CLAMP = 3,D3DTADDRESS_BORDER = 4,D3DTADDRESS_MIRRORONCE = 5,D3DTADDRESS_FORCE_DWORD = 0×7fffffff,} D3DTEXTUREADDRESS, *LPD3DTEXTUREADDRESS;
Wrap,类似于平铺,就是把这个图片复制很多份,然后像铺瓦片一样一片一片拼起来。
Mirror,和Wrap差不多,唯一不同的是相邻两个拷贝之间是镜像关系。
Clamp,就是超出部分直接抛弃。
Mirror_Once,就是先将图片镜像一份,从而u和v的坐标范围就变成了-1~1了。
posted @ 2009-09-25 10:43 koilin 阅读(336) | 评论 (0) | 编辑 收藏
posted @ 2009-09-24 21:11 koilin 阅读(710) | 评论 (0) | 编辑 收藏
(3)
对于多面体上参数化的点可以表示为,我们考虑多面体的一个三角形面,对应的三个顶点为,即为该三角形的经典重心坐标。三角形单位球上的投影为球面三角形,与三个顶点形成的方向向量可以组成一个楔形,如图 1所示。从而可以离散化为
(4)
其中,。
图 1 均值坐标对应的楔形图
在球面三角形上定义一个均值向量,其中。根据均值理论,,可以得到,最后归一化得到相对于多面体上顶点的重心坐标。
由于在均值坐标的建立过程中,多面体上点与任意点之间采用欧氏距离,当多面体为凹时,此距离包含了多面体的外部,从而均值坐标不满足内部局部性。同时均值向量和多面体表面的法向一致,当多面体为凹时,均值坐标可能为负,因此均值坐标不满足非负性。
posted @ 2009-09-19 13:58 koilin 阅读(1520) | 评论 (0) | 编辑 收藏
Powered by: C++博客 Copyright © koilin