directx11.0怎么安装 depth buffer怎么比较

混合语言编程—C#使用原生的Directx和OpenGL绘图的方法
字体:[ ] 类型:转载 时间:
本文要说的是混合C#和C/C++语言编程,在C#的Winform和WPF下使用原生的Direct和OpenGL进行绘图
由于项目需要做一些图形展示,所以就想到了使用Directx和OpenGL来绘图,但项目准备使用C#来开发(大家比较熟悉C#),在网上看了相关的资料,有一些第三方的控件可用,试用了下,一运行就占了几百M的内存,而且也不知道是否稳定,教程也少,还不如直接使用原生的。在网上看的Directx和OpenGL的教程基本上都是C/C++的,找了很久也就找到相关介绍,只能自己研究下。
我以前做过C#和C++混合语言编程相关的东西,在C++实现一些C#不好实现的功能,C#动态调用DLL文件,所以也想到了用C++的代码来控制Winform控件的绘画,这样就可实现用Direct和OpenGL在Winform的控件上绘画了。
由于我对Direct和OpenGL都不熟悉,没有这方面的编程经验,只能去瞎折腾,下面分别说说最近在Directx和OpenGL怎么试验的。
之前没学过Directx,拿了同学的代码来看,也是雾里看花啊,不过有一点启示了我,在初始化的时候,要传入一个句柄去创建设备(CreateDevice),通常都是传入窗口的设备,我想如果传入一个控件的句柄,那所有的绘画都将在这个控件上实现,因为控件也是继承自Window的。而Winform的控件在底层的实现应该和WIN32是一样的。这样的话只要把Winform的控件的句柄传入C++代码进行初始化,那么绘画的结果将显示在这个控件上。结果一试,还真行。关键代码如下: 代码如下:extern "C" _declspec(dllexport) HRESULT InitD3D( HWND hWnd );
extern "C" _declspec(dllexport) VOID Render();
在InitD3D传入控件的句柄进行初始化,C#再调用Render进行绘画,以下是C#代码: 代码如下:HWND handle = this.button1.H
InitD3D(handle);
private void Draw()
&&&&&&&& for (; ; )
&&&&&&&&&&& {
&&&&&&&&&&&&&&& Render();
&&&&&&&&&&& }
&&&&&&& }&效果图:
OpenGL:&&&&&&&& 查看了OpenGL的相关教程(推荐http://www.yakergong.net/nehe/),OpenGL是通过RC来执行的,创建RC时就必须指定一个DC,还要设置DC的像素格式。每个线程有且只能拥有一个RC。&&&&&&&& 如果在初始化OpenGL的绘画环境时传入一个Winform的控件句柄,再通过这个句柄取到HDC,就可使用这个HDC来创建RC,这样OpenGL的绘画环境就准备好了,并且这个RC关联到Winform的控件上。&&&&&&&& 在给制前,先为当前线程选择RC(之前通过HDC创建的),再进行绘制,这样绘制的结果将显示在这个Winform控件上。&&&&&&&& 关键代码如下:C++: 代码如下:extern "C" _declspec(dllexport) void Init( HWND hWnd);extern "C" _declspec(dllexport) void Render();void Init(HWND hWnd){&& int PixelF&& int bits = 16;&& hDC = GetDC(hWnd);&& static& PIXELFORMATDESCRIPTOR pfd=&&&&&&&&&& // pfd Tells Windows How We Want Things To Be&& {&&&&& sizeof(PIXELFORMATDESCRIPTOR),&&&&&&&&&&&&& // Size Of This Pixel Format Descriptor&&&&& 1,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&    // Version Number&&&&& PFD_DRAW_TO_WINDOW |&&&&&&&&&&&&&&&&&&&&&&& // Format Must Support Window&&&&& PFD_SUPPORT_OPENGL |&&&&&&&&&&&&&&&&&&&&&&&&& // Format Must Support OpenGL&&&&& PFD_DOUBLEBUFFER,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Must Support Double Buffering&&&&& PFD_TYPE_RGBA,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Request An RGBA Format&&&&& bits,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Select Our Color Depth&&&&& 0, 0, 0, 0, 0, 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Color Bits Ignored&&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // No Alpha Buffer&&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Shift Bit Ignored&&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // No Accumulation Buffer&&&&& 0, 0, 0, 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Accumulation Bits Ignored&&&&& 16,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // 16Bit Z-Buffer (Depth Buffer) &&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // No Stencil Buffer&&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // No Auxiliary Buffer&&&&& PFD_MAIN_PLANE,&&&&&&&&&&&&&&&&&&&&&&&& // Main Drawing Layer&&&&& 0,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Reserved&&&&& 0, 0, 0&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Layer Masks Ignored&& };&& PixelFormat=ChoosePixelFormat(hDC,&pfd);&& SetPixelFormat(hDC,PixelFormat,&pfd);&& hRC=wglCreateContext(hDC);}void Render(){&& wglMakeCurrent(hDC, hRC);&& draw();&& SwapBuffers(hDC);&& wglMakeCurrent(NULL, NULL);}C#: 代码如下:Init(this.pictureBox1.Handle);//开始绘制var timer = new System.Timers.Timer();timer.Interval = 100;&timer.Elapsed += (tsender, te) =&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&& Render();&&&&&&&&&&&&&&& };timer.AutoReset =timer.Enabled =效果图:
WPF:WPF的控件没有句柄,但是可以换个思路,把绘画代码封装在Winform控件上,在WPF使用自定义的Winform控件。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具随笔 - 252, 文章 - 0, 评论 - 208, 引用 - 0
     在D3D11中,有depth/stencil buffer,它们和framebuffer相对应,如下图所示,framebuffer中一个像素,有相对应的depth buffer和stencil buffer值:
      D3D11中,depth buffer和stencil buffer一起定义,比如DXGI_FORMAT_D24_UNORM_S8_UINT,是指用一个无符号24位的值做为像素的深度缓冲值,并把它映射到[0,1],用一个8位的值表示像素stencil值,并把它映射到[0,255]。注意:在hardware中,detph buffer和stencil buffer实际上是两个独立的buffer。
     
     下面我们看看depth buffer和stencil buffer的作用:
      在光栅化阶段,光栅化硬件在光栅化primitive(比如一个三角形)的时候,会访问stencil buffer和depth buffer,并进行相应的比较,这种比较我们通常称为stencil test和depth test,只有通过stencil test和depth test的pixel(或者称为sample 或者fragment更合适),才能最终被写入framebuffer。
     下图是stencil test和depth test的框图:
       首先会进行stecil test,就是当前pixel的stencil值和stencil buffer中对应的stencil值进行某种比较,只有通过比较测试的pixel才会进行depth test,否则就会被光栅化硬件丢弃掉。接着会进行depth test,depth test能够保证物体在场景中前后位置关系。如果两个test都pass,就会更新depth buffer值(当然stencil pass的时候,就可以根据stencil function更新或者保持stencil buffer值了)。
    通过使用stencil test,我们可以实现蒙版的效果,从而实现一些渲染效果,比如镜子,体积阴影等。
举个例子:
    在一个frame中,我们首先渲染一个四边形,做为镜子,渲染前,清除depth/stencil buffer值(depth设置为1.0, stencil 设置为0),这时场景中stencil buffer为
接着,我们设置stencil 总是pass,并设置stencil buffer值为1,渲染一个镜子(四边形)。这是stencil buffer的值为
接下来,我们渲染其它的primitive,比如一个三角形,先设置stencil 值为1,并设置stencil比较函数为等于,这样渲染三角形时候,会比较stencil值,对于三角形光栅化后的pixel,如果它在镜子的范围内,1=1,所以stencil pass,会保留这个像素,如果在镜子的外面,因为stencil buffer的值为0,所以stencil test fail,从而放弃这个pixel。如下图三角形,最后实际保留的像素只为蓝色的pass stencil test的部分。
   下面一章,我们将在D3D11中,通过使用stencil,实现一个镜子的效果。本文由zhangbaochong原创,转载请注明出处
  在前面我们曾经实现过简单的地形(),只不过原来使用一个固定的函数获得地形高度,这样跟真实的地形差距比较大。接下来让我们学习使用高度图来进行三维地形模拟。
  高度图其实就是一组连续的数组,这个数组中的元素与地形网格中的顶点一一对应,且每一个元素都指定了地形网格的某个顶点的高度值。高度图最常用的使用灰度图实现,灰度图中亮度越大对应的地形高度越高。下面就是一幅灰度图:
  灰度图格式通常为.raw,google一下高度图保存图片改为raw格式就可以了。高度图每个元素通常只分配一个字节,即数值在0~255之间。但在实际使用的时候经常要对高度进行比例变换,因此需要将byte转为float,然后通过一个缩放系数进行缩放,这样就不必拘泥于0~255这么一个范围了。
2.读取高度图
  读取高度图很简单,用二进制读取文件就好了。
1 //读取高度图信息
2 bool TerrainDemo::ReadRawFile(std::string filePath)
std::ifstream inF
//二进制方式打开文件
inFile.open(filePath.c_str(), std::ios::binary);
//文件指针移动到末尾
inFile.seekg(0, std::ios::end);
//大小为当前缓冲区大小
std::vector&BYTE& inData(inFile.tellg());
//文件指针移动到开头
inFile.seekg(std::ios::beg);
//读取高度信息
inFile.read((char*)&inData[0], inData.size());
inFile.close();
m_heightInfos.resize(inData.size());
for (int i = 0; i & inData.size(); ++i)
m_heightInfos[i] = inData[i];
return true;
3.顶点和索引的计算
  顶点和索引的计算同类似,这里就不再详细说明了。不一样的由于采用了纹理光照渲染,所以需要得到法线,在计算索引的同时需要把顶点法线计算出来:
1 //计算法线
2 void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
XMFLOAT3 f1(v2.pos.x - v1.pos.x, v2.pos.y - v1.pos.y, v2.pos.z - v1.pos.z);
XMFLOAT3 f2(v3.pos.x - v1.pos.x, v3.pos.y - v1.pos.y, v3.pos.z - v1.pos.z);
XMVECTOR vec1 = XMLoadFloat3(&f1);
XMVECTOR vec2 = XMLoadFloat3(&f2);
XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
XMStoreFloat3(&normal, temp);
  计算顶点和索引:
1 bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n,float scale)
m_cellsPerRow =
m_cellsPerCol =
m_verticesPerRow = m + 1;
m_verticesPerCol = n + 1;
m_numsVertices = m_verticesPerRow*m_verticesPerC
m_height =
m_heightScale =
//得到缩放后的高度
for (auto& item : m_heightInfos)
item *= m_heightS
//起始x z坐标
float oX = -width * 0.5f;
float oZ = height * 0.5f;
//每一格坐标变化
float dx = width /
float dz = height /
m_vertices.resize(m_numsVertices);
//计算顶点
for (UINT i = 0; i & m_verticesPerC ++i)
float tempZ = oZ - dz *
for (UINT j = 0; j & m_verticesPerR ++j)
UINT index = m_verticesPerRow * i +
m_vertices[index].pos.x = oX + dx *
m_vertices[index].pos.y = m_heightInfos[index];
m_vertices[index].pos.z = tempZ;
m_vertices[index].tex = XMFLOAT2(dx*i, dx*j);
//计算索引和法线
//总格子数量:m * n
//因此总索引数量: 6 * m * n
UINT nIndices = m * n * 6;
m_indices.resize(nIndices);
UINT tmp = 0;
for (UINT i = 0; i & ++i)
for (UINT j = 0; j & ++j)
m_indices[tmp] = i * m_verticesPerRow +
m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 2] = (i + 1) * m_verticesPerRow +
//计算法线
ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]],
m_vertices[m_indices[tmp + 2]], temp);
m_vertices[m_indices[tmp]].normal =
m_vertices[m_indices[tmp + 1]].normal =
m_vertices[m_indices[tmp + 2]].normal =
m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
m_indices[tmp + 5] = (i + 1) * m_verticesPerRow +
ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
m_vertices[m_indices[tmp + 5]], temp);
m_vertices[m_indices[tmp + 3]].normal =
m_vertices[m_indices[tmp + 4]].normal =
m_vertices[m_indices[tmp + 5]].normal =
return true;
4.效果截图
5.详细源码
TerrainDemo.h
1 #pragma once
2 #include &string&
3 #include &vector&
4 #include "Dx11Base.h"
5 #include "Camera.h"
6 #include "Input.h"
7 #include "Utility.h"
8 #include "LightHelper.h"
10 class TerrainDemo : public Dx11Base
12 public:
TerrainDemo(HINSTANCE hInst, std::wstring title = L"TerrainDemo", int width = 800, int height = 640);
~TerrainDemo();
//顶点结构 位置、法线、uv坐标
struct Vertex
Vertex() {}
Vertex(const XMFLOAT3 _pos, XMFLOAT3 _normal,
XMFLOAT2 _tex) :
pos(_pos), normal(_normal),
tex(_tex) {}
bool Init() override;
void Update(float dt);
void Render();
bool OnResize() override;
33 private:
bool BuildBuffers();
bool BuildSRVs();
bool BuildInputLayouts();
void UpdateCamera(float dt);
38 private:
bool ReadRawFile(std::string filePath);
//从高度图读取高度信息
bool InitTerrain(float width, float height, UINT m, UINT n, float scale);
//初始化地形
void ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal);
//计算法线
42 private:
std::vector&float&
//高度图高度信息
m_cellsPerR
//每行单元格数
m_cellsPerC
//每列单元格数
m_verticesPerR
//每行顶点数
m_verticesPerC
//每列顶点数
//顶点总数
//地形宽度
//地形高度
//高度缩放系数
std::vector&Vertex&
//顶点集合
std::vector&UINT&
//索引集合
56 private:
ID3D11Buffer*
m_pVertexB
ID3D11Buffer*
ID3D11InputLayout*
ID3D11ShaderResourceView*
Lights::DirectionalLight
m_dirLights[3];
//3个平行光源
Lights::Material
m_materialT
XMFLOAT4X4
//世界变换矩阵
XMFLOAT4X4
m_worldViewP
//世界视角投影矩阵
XMFLOAT4X4
m_worldInvT
//世界逆矩阵的转置,用于法线变换
XMFLOAT4X4
//纹理坐标变换矩阵
m_lastMouseP
TerrainDemo.cpp
1 #include &fstream&
2 #include &memory&
3 #include "TerrainDemo.h"
4 #include "Utility.h"
5 #include "WICTextureLoader.h"
6 #include "d3dx11effect.h"
7 #include "Effects.h"
9 TerrainDemo::TerrainDemo(HINSTANCE hInst, std::wstring title, int width, int height)
:Dx11Base(hInst, title, width, height)
//"三点式"照明
m_dirLights[0].ambient = XMFLOAT4(0.3f, 0.3f, 0.3f, 1.0f);
m_dirLights[0].diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
m_dirLights[0].specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
m_dirLights[0].direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);
m_dirLights[1].ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
m_dirLights[1].diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f);
m_dirLights[1].specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
m_dirLights[1].direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f);
m_dirLights[2].ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
m_dirLights[2].diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
m_dirLights[2].specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
m_dirLights[2].direction = XMFLOAT3(0.0f, -0.707f, -0.707f);
m_materialTerrain.ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
m_materialTerrain.diffuse = XMFLOAT4(1.f, 1.f, 1.f, 1.0f);
m_materialTerrain.specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 16.0f);
//设置相机
m_lastMousePos = { 0,0 };
XMVECTOR Eye = XMVectorSet(0.0f, 50.0f, 0.1f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_camera.LookAtXM(Eye, At, Up);
//设置投影矩阵
m_camera.SetLens(XM_PIDIV4, AspectRatio(), 0.1f, 1000.f);
//初始化世界矩阵 逆转置矩阵 及纹理坐标矩阵
//这些每一帧不改变
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&m_world, I);
XMVECTOR det = XMMatrixDeterminant(I);
XMMATRIX worldInvTranspose = XMMatrixTranspose(XMMatrixInverse(&det,I));
XMStoreFloat4x4(&m_worldInvTranspose, worldInvTranspose);
XMStoreFloat4x4(&m_texTrans, I);
53 TerrainDemo::~TerrainDemo()
SafeRelease(m_pVertexBuffer);
SafeRelease(m_pIndexBuffer);
SafeRelease(m_pInputLayout);
SafeRelease(m_pSRVTerrain);
Effects::ReleaseAll();
62 bool TerrainDemo::Init()
if (!Dx11Base::Init())
return false;
if (!Effects::InitAll(m_pd3dDevice))
return false;
if (!ReadRawFile("Texture\\heightmap.raw"))
return false;
if (!InitTerrain(500, 500, 255, 255, 0.2f))
return false;
if (!BuildBuffers())
return false;
if (!BuildSRVs())
return false;
if (!BuildInputLayouts())
return false;
80 void TerrainDemo::Update(float dt)
UpdateCamera(dt);
XMMATRIX world = XMLoadFloat4x4(&m_world);
XMMATRIX worldViewProj = world * m_camera.GetViewProj();
XMStoreFloat4x4(&m_worldViewProj, worldViewProj);
//设置灯光
Effects::ms_pBasicEffect-&m_pFxDirLights-&SetRawValue(&m_dirLights, 0,
3 * sizeof(Lights::DirectionalLight));
Effects::ms_pBasicEffect-&m_pFxEyePos-&SetRawValue(&m_camera.GetPosition(), 0,
sizeof(m_camera.GetPosition()));
94 void TerrainDemo::Render()
m_pImmediateContext-&ClearRenderTargetView(m_pRenderTargetView, Colors::Silver);
m_pImmediateContext-&ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_pImmediateContext-&IASetInputLayout(m_pInputLayout);
UINT stride = sizeof(Vertex);
UINT offset = 0;
m_pImmediateContext-&IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
m_pImmediateContext-&IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, offset);
m_pImmediateContext-&IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3DX11_TECHNIQUE_DESC
ID3DX11EffectTechnique* tech = Effects::ms_pBasicEffect-&m_pFxLight3TexT
tech-&GetDesc(&desc);
for (UINT i = 0; i & desc.P ++i)
//设置着色器变量
Effects::ms_pBasicEffect-&m_pFxWorld-&SetMatrix(reinterpret_cast&const float*&(&m_world));
Effects::ms_pBasicEffect-&m_pFxWorldViewProj-&SetMatrix(reinterpret_cast&const float*&(
&m_worldViewProj));
Effects::ms_pBasicEffect-&m_pFxWorldInvTranspose-&SetMatrix(reinterpret_cast&const float*&(
&m_worldInvTranspose));
Effects::ms_pBasicEffect-&m_pFxTexTrans-&SetMatrix(reinterpret_cast&const float*&(
&m_texTrans));
Effects::ms_pBasicEffect-&m_pFxMaterial-&SetRawValue(&m_materialTerrain, 0, sizeof(m_materialTerrain));
Effects::ms_pBasicEffect-&m_pFxSR-&SetResource(m_pSRVTerrain);
tech-&GetPassByIndex(i)-&Apply(0, m_pImmediateContext);
m_pImmediateContext-&DrawIndexed(m_indices.size(), 0, 0);
m_pSwapChain-&Present(0, 0);
129 bool TerrainDemo::OnResize()
if (!Dx11Base::OnResize())
return false;
//更新camera参数
m_camera.SetLens(XM_PIDIV4, AspectRatio(), 1.f, 1000.f);
return true;
139 bool TerrainDemo::BuildBuffers()
//创建顶点缓冲区
D3D11_BUFFER_DESC vertexD
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(Vertex) * m_numsV
vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
D3D11_SUBRESOURCE_DATA vertexD
vertexData.pSysMem = &m_vertices[0];
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
if (FAILED(m_pd3dDevice-&CreateBuffer(&vertexDesc, &vertexData, &m_pVertexBuffer)))
MessageBox(nullptr, L"Create Vertex Buffer failed!", L"Error", MB_OK);
return false;
//创建索引缓冲区
D3D11_BUFFER_DESC indexD
ZeroMemory(&indexDesc, sizeof(indexDesc));
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexDesc.ByteWidth = sizeof(UINT) * m_indices.size();
indexDesc.Usage = D3D11_USAGE_IMMUTABLE;
D3D11_SUBRESOURCE_DATA indexD
indexData.pSysMem = &m_indices[0];
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
if (FAILED(m_pd3dDevice-&CreateBuffer(&indexDesc, &indexData, &m_pIndexBuffer)))
MessageBox(nullptr, L"Create Index Buffer failed!", L"Error", MB_OK);
return false;
return true;
178 bool TerrainDemo::BuildSRVs()
if (FAILED(CreateWICTextureFromFile(m_pd3dDevice, L"Texture\\desert.bmp", nullptr, &m_pSRVTerrain)))
MessageBox(nullptr, L"create texture failed!", L"error", MB_OK);
return false;
return true;
188 bool TerrainDemo::BuildInputLayouts()
D3D11_INPUT_ELEMENT_DESC layout[] =
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL",
0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12,D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,
0, 24,D3D11_INPUT_PER_VERTEX_DATA, 0 }
UINT numLayoutElements = ARRAYSIZE(layout);
D3DX11_PASS_DESC passD
Effects::ms_pBasicEffect-&m_pFxLight3TexTech-&GetPassByIndex(0)-&GetDesc(&passDesc);
if (FAILED(m_pd3dDevice-&CreateInputLayout(layout, numLayoutElements, passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize, &m_pInputLayout)))
MessageBox(nullptr, L"create inputLayout failed!", L"error", MB_OK);
return false;
return true;
209 void TerrainDemo::UpdateCamera(float dt)
//前后左右行走
if (Input::GetInstance()-&IsKeyDown('A'))
m_camera.Strafe(-60.f*dt);
else if (Input::GetInstance()-&IsKeyDown('D'))
m_camera.Strafe(60.f*dt);
if (Input::GetInstance()-&IsKeyDown('W'))
m_camera.Walk(60.f*dt);
else if (Input::GetInstance()-&IsKeyDown('S'))
m_camera.Walk(-60.f*dt);
if (Input::GetInstance()-&IsMouseMove())
float mouseX = Input::GetInstance()-&GetMouseX();
float mouseY = Input::GetInstance()-&GetMouseY();
if (Input::GetInstance()-&IsLMouseDown())
float dx = XMConvertToRadians(0.25f*(mouseX - m_lastMousePos.x));
float dy = XMConvertToRadians(0.25f*(mouseY - m_lastMousePos.y));
OutputDebugString(L"left btn click");
m_camera.Pitch(dy);
m_camera.RotateY(dx);
m_lastMousePos.x = mouseX;
m_lastMousePos.y = mouseY;
m_camera.UpdateViewMatrix();
250 //读取高度图信息
251 bool TerrainDemo::ReadRawFile(std::string filePath)
std::ifstream inF
//二进制方式打开文件
inFile.open(filePath.c_str(), std::ios::binary);
//文件指针移动到末尾
inFile.seekg(0, std::ios::end);
//大小为当前缓冲区大小
std::vector&BYTE& inData(inFile.tellg());
//文件指针移动到开头
inFile.seekg(std::ios::beg);
//读取高度信息
inFile.read((char*)&inData[0], inData.size());
inFile.close();
m_heightInfos.resize(inData.size());
for (int i = 0; i & inData.size(); ++i)
m_heightInfos[i] = inData[i];
return true;
275 bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n,float scale)
m_cellsPerRow =
m_cellsPerCol =
m_verticesPerRow = m + 1;
m_verticesPerCol = n + 1;
m_numsVertices = m_verticesPerRow*m_verticesPerC
m_height =
m_heightScale =
//得到缩放后的高度
for (auto& item : m_heightInfos)
item *= m_heightS
//起始x z坐标
float oX = -width * 0.5f;
float oZ = height * 0.5f;
//每一格坐标变化
float dx = width /
float dz = height /
m_vertices.resize(m_numsVertices);
//计算顶点
for (UINT i = 0; i & m_verticesPerC ++i)
float tempZ = oZ - dz *
for (UINT j = 0; j & m_verticesPerR ++j)
UINT index = m_verticesPerRow * i +
m_vertices[index].pos.x = oX + dx *
m_vertices[index].pos.y = m_heightInfos[index];
m_vertices[index].pos.z = tempZ;
m_vertices[index].tex = XMFLOAT2(dx*i, dx*j);
//计算索引和法线
//总格子数量:m * n
//因此总索引数量: 6 * m * n
UINT nIndices = m * n * 6;
m_indices.resize(nIndices);
UINT tmp = 0;
for (UINT i = 0; i & ++i)
for (UINT j = 0; j & ++j)
m_indices[tmp] = i * m_verticesPerRow +
m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 2] = (i + 1) * m_verticesPerRow +
//计算法线
ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]],
m_vertices[m_indices[tmp + 2]], temp);
m_vertices[m_indices[tmp]].normal =
m_vertices[m_indices[tmp + 1]].normal =
m_vertices[m_indices[tmp + 2]].normal =
m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
m_indices[tmp + 5] = (i + 1) * m_verticesPerRow +
ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
m_vertices[m_indices[tmp + 5]], temp);
m_vertices[m_indices[tmp + 3]].normal =
m_vertices[m_indices[tmp + 4]].normal =
m_vertices[m_indices[tmp + 5]].normal =
return true;
354 //计算法线
355 void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
XMFLOAT3 f1(v2.pos.x - v1.pos.x, v2.pos.y - v1.pos.y, v2.pos.z - v1.pos.z);
XMFLOAT3 f2(v3.pos.x - v1.pos.x, v3.pos.y - v1.pos.y, v3.pos.z - v1.pos.z);
XMVECTOR vec1 = XMLoadFloat3(&f1);
XMVECTOR vec2 = XMLoadFloat3(&f2);
XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
XMStoreFloat3(&normal, temp);
365 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
std::shared_ptr&Dx11Base& bd(new TerrainDemo(hInstance));
if (!bd-&Init())
return -1;
return bd-&Run();
阅读(...) 评论()

我要回帖

更多关于 directx11怎么安装 的文章

 

随机推荐