主菜终于来了。这个d3dclass主要做的工作是dx11图形程序的初始化工作,它将创建显示表面交换链,d3d设备,d3d设备上下文,渲染目标表面,深度模板缓存;设置视口,生成投影矩阵。

  • D3D设备:可以看成是一个接口,获得这个接口后就能创建各种d3d对象
  • D3D设备上下文:应该也可以看成是渲染环境的接口吧,使用它就能定制各种渲染环境,对绘制环境进行配置
  • 显示表面交换链:显示表面的集合,显示表面是什么?是当前屏幕内容的内存映射,这或许应该说是主显示表面,与主显示表面同在交换链里的是副显示表面。它们的出现是为了实现平滑的绘制效果
  • 渲染目标表面:就是交换链当前处于后台的表面(副表面)
  • 深度模板缓存:一个存储当前绘制了的像素对应的Z值的数据块,通过这个缓存块可以决定我们是否能看到模型。就像我们把两张纸放在我们的眼前,我们只能看到离我们近的那张,离我们远的那张被离的近的挡住了,这个远近的量化就是Z值。
  • 视口:显示图形的矩形,如果是全屏,那么视口就是当前屏幕
  • 投影矩阵:3d渲染管线中一个重要的矩阵,他能将相机看到的内容投影到视口上

代码:

d3dclass.h

 #pragma once

 #include <d3d11.h>
 #include <d3dcompiler.h>
 #include <D3DX11.h>
 #include <xnamath.h>

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

 class d3dclass
 {
 public:
     d3dclass();
     ~d3dclass();

 private:
     ID3D11Device *m_d3ddevice;
     ID3D11DeviceContext *m_d3dcontext;
     IDXGISwapChain *m_d3dswapchain;
     ID3D11RenderTargetView *m_d3dtargetview;
     ID3D11Texture2D* m_d3ddepthStencil;
     ID3D11DepthStencilView* m_d3ddepthStencilView;
     XMMATRIX m_pro;

 public:
     bool Initialize(HWND hwnd);
     void Shutdown();
     void Getdevice(ID3D11Device*& device);
     void Getcontext(ID3D11DeviceContext*& context);
     void Beginrender(float r, float g, float b, float a);
     void Endrender();
     void Getpromtrx(XMMATRIX& pro);
 };

m_d3ddevice:d3d设备对象

m_d3dcontext:d3d设备上下文

m_d3dswapchain:d3d交换链

m_d3dtargetview:渲染目标表面

m_d3ddepthStencil:深度缓存

m_d3ddepthStencilView:深度缓存表面

m_pro:投影矩阵

公有方法作用:

Initialize():初始化directx的各种对象

Shutdown():释放各种对象

Getdevice():获取设备指针以供使用

Getcontext():获取设备上下文指针以供使用

Beginrender():在模型渲染前调用

Endrender():在模型渲染后调用

Getpromatrx():获取投影矩阵以供使用

d3dclass.cpp

 #include "d3dclass.h"

 d3dclass::d3dclass()
 {
 }

 d3dclass::~d3dclass()
 {
 }

 bool d3dclass::Initialize(HWND hwnd)
 {
     HRESULT hr = S_OK;
     D3D_DRIVER_TYPE drivertype;
     D3D_FEATURE_LEVEL featurelevel;

     RECT rc;
     GetClientRect(hwnd, &rc);
     int width = rc.right - rc.left;
     int height = rc.bottom - rc.top;

     UINT createDeviceFlags = ;
 #ifdef _DEBUG
     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
 #endif

     D3D_DRIVER_TYPE driverTypes[] =
     {
         D3D_DRIVER_TYPE_HARDWARE,
         D3D_DRIVER_TYPE_WARP,
         D3D_DRIVER_TYPE_REFERENCE,
     };
     UINT numDriverTypes = ARRAYSIZE(driverTypes);

     D3D_FEATURE_LEVEL featureLevels[] =
     {
         D3D_FEATURE_LEVEL_11_0,
         D3D_FEATURE_LEVEL_10_1,
         D3D_FEATURE_LEVEL_10_0,
     };
     UINT numFeatureLevels = ARRAYSIZE(featureLevels);

     DXGI_SWAP_CHAIN_DESC sd;
     ZeroMemory(&sd, sizeof(sd));
     sd.BufferCount = ;///////////////
     sd.BufferDesc.Width = width;
     sd.BufferDesc.Height = height;
     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
     sd.BufferDesc.RefreshRate.Numerator = ;
     sd.BufferDesc.RefreshRate.Denominator = ;
     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
     sd.OutputWindow = hwnd;
     sd.SampleDesc.Count = ;//////////////
     sd.SampleDesc.Quality = ;/////////////
     sd.Windowed = TRUE;

     ; driverTypeIndex < numDriverTypes; driverTypeIndex++)
     {
         drivertype = driverTypes[driverTypeIndex];
         hr=D3D11CreateDeviceAndSwapChain(NULL, drivertype, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
             D3D11_SDK_VERSION, &sd, &m_d3dswapchain, &m_d3ddevice, &featurelevel, &m_d3dcontext);
         if (SUCCEEDED(hr))
         {
             break;
         }
     }
     if (FAILED(hr))
     {
         return false;
     }

     ID3D11Texture2D* pBackBuffer = NULL;
     hr = m_d3dswapchain->GetBuffer(, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
     if (FAILED(hr))
     {
         return false;
     }

     hr = m_d3ddevice->CreateRenderTargetView(pBackBuffer, NULL, &m_d3dtargetview);

     pBackBuffer->Release();
     if (FAILED(hr))
     {
         return false;
     }

     D3D11_TEXTURE2D_DESC descDepth;
     ZeroMemory(&descDepth, sizeof(descDepth));
     descDepth.Width = width;
     descDepth.Height = height;
     descDepth.MipLevels = ;
     descDepth.ArraySize = ;
     descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
     descDepth.SampleDesc.Count = ;
     descDepth.SampleDesc.Quality = ;
     descDepth.Usage = D3D11_USAGE_DEFAULT;
     descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
     descDepth.CPUAccessFlags = ;
     descDepth.MiscFlags = ;
     hr = m_d3ddevice->CreateTexture2D(&descDepth, NULL, &m_d3ddepthStencil);
     if (FAILED(hr))
     {
         return false;
     }    

     D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
     ZeroMemory(&descDSV, sizeof(descDSV));
     descDSV.Format = descDepth.Format;
     descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
     descDSV.Texture2D.MipSlice = ;
     hr = m_d3ddevice->CreateDepthStencilView(m_d3ddepthStencil, &descDSV, &m_d3ddepthStencilView);
     if (FAILED(hr))
     {
         return false;
     }

     m_d3dcontext->OMSetRenderTargets(, &m_d3dtargetview, m_d3ddepthStencilView);

     D3D11_VIEWPORT vp;
     vp.Width = (FLOAT)width;
     vp.Height = (FLOAT)height;
     vp.MinDepth = 0.0f;
     vp.MaxDepth = 1.0f;
     vp.TopLeftX = ;
     vp.TopLeftY = ;
     m_d3dcontext->RSSetViewports(, &vp);

     m_pro = XMMatrixPerspectiveFovLH(XM_PIDIV2, (float)width / (float)height, 0.01f, 1000.0f);

     return true;
 }

 void d3dclass::Shutdown()
 {
     if (m_d3dtargetview)
     {
         m_d3dtargetview->Release();
     }
     if (m_d3ddepthStencilView)
     {
         m_d3ddepthStencilView->Release();
     }
     if (m_d3ddepthStencil)
     {
         m_d3ddepthStencil->Release();
     }
     if (m_d3dswapchain)
     {
         m_d3dswapchain->Release();
     }
     if (m_d3dcontext)
     {
         m_d3dcontext->Release();
     }
     if (m_d3ddevice)
     {
         m_d3ddevice->Release();
     }
 }

 void d3dclass::Getdevice(ID3D11Device*& device)
 {
     device = m_d3ddevice;
 }

 void d3dclass::Getcontext(ID3D11DeviceContext*& context)
 {
     context = m_d3dcontext;
 }

 void d3dclass::Beginrender(float r,float g,float b,float a)
 {
     float color[] = { r, g, b, a };
     m_d3dcontext->ClearRenderTargetView(m_d3dtargetview,color);
     m_d3dcontext->ClearDepthStencilView(m_d3ddepthStencilView, D3D11_CLEAR_DEPTH, );
 }

 void d3dclass::Endrender()
 {
     m_d3dswapchain->Present(, );
 }

 void d3dclass::Getpromtrx(XMMATRIX& pro)
 {
     pro = m_pro;
 }

具体来看这几个方法。

Initialize():

  • 先罗列设备类型与特征层级,填充交换链描述数据结构,然后for循环测试使用哪个设备类型与特征层级,创建交换链,设备,设备上下文;
  • 再获取一个二维内存,创建渲染目标表面;
  • 再填充一个二维内存描述数据结构,创建一个二维内存,填充一个深度模板缓存描述数据结构,创建深度模板缓存,并设置之;
  • 创建视口数据结构,填充各个字段,并设置;
  • 最后生成投影矩阵

至于各个描述数据结构的各个字段含义,大家可以去查阅dx11的文档

(本函数没有进行设备性能检测,所以是不安全的代码,大家如果要深入学习,还是要多参考其他资料)

Shutdown():依前是释放对象时做扫尾工作

Beginrender():用指定颜色清理渲染目标表面,并清理深度缓存

Endrender():交换交换链的显示表面

C++小项目:directx11图形程序(四):d3dclass的更多相关文章

  1. C++小项目:directx11图形程序(一):主框架

    最近在学习DIRECTX11,在学习过程中编写了一个程序,到现在发现这个程序也有几行代码了,结构还算整齐,就想把这个程序分享出来,其中涉及到了C++程序的架构,windows窗口程序编写,和Direc ...

  2. C++小项目:directx11图形程序(三):graphicsclass

    这是框架的第三层graphicsclass,这个类才真正可以说是整个程序的框架,因为它组织了后面所有的成员. 代码: graphicsclass.h #pragma once #include< ...

  3. C++小项目:directx11图形程序(九):总结

    整篇文章中对于directx11的知识的介绍并不多,我也不知道怎么介绍,也应该说对于directx,它有它自己的部分,比如设备(device),设备上下文(devicecontext),顶点缓存,索引 ...

  4. C++小项目:directx11图形程序(八):particleSysclass

    粒子系统类,粒子系统是游戏里细小元素的控制系统,虽然感觉上它对游戏的影响不大,但是其实有了它能给游戏增色不少.粒子系统控制着细小元素的生死,运动,纹理.对它的编写让我知道,游戏里的这一片从天空飘落的雪 ...

  5. C++小项目:directx11图形程序(七):modelclass

    模型类是世界空间中的表示物体的类,那么他的所做的事就是加载模型,移动模型,渲染模型 modelclass.h #pragma once #include <d3d11.h> #includ ...

  6. C++小项目:directx11图形程序(二):systemclass

    先上代码: systemclass.h #pragma once #include"graphicsclass.h" const bool FULLSCREEN = true; c ...

  7. C++小项目:directx11图形程序(六):cameraclass

    cameraclass是一个相机类,它的作用是生成非常重要的观察矩阵.本小节涉及到一点数学知识,相对前面需要只是填充,调用,算是比较有趣的吧. cameraclass.h #pragma once # ...

  8. C++小项目:directx11图形程序(五):shadersclass

    这个类是用来创建着色器并设置输入布局的. 这个类比较特殊,它创建的着色器与Effect文件有关,effect文件是用高级着色语言(hlsl)编写的. shadersclass.h #pragma on ...

  9. Android小项目之七 应用程序的更新安装

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

随机推荐

  1. hihocoder1241 Best Route in a Grid

    题目链接:hihocoder 1241 题意: n*n的格阵,每个方格内有一个数字.蚂蚁从左上角走到右下角,数字是零的方格不能走,只能向右向下走.蚂蚁走的路径上全部方格的的乘积为s,要使s低位0的个数 ...

  2. STL next_permutation和prev_permutation函数

    利用next_permutation实现全排列升序输出,从尾到头找到第一个可以交换的位置, 直接求到第一个不按升序排列的序列. #include <iostream> #include & ...

  3. [Android Pro] 关于inputStream.available()方法获取文件的总大小

    reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...

  4. JS事件委托的原理和应用

    js事件委托也叫事件代理,实际上事件委托就是通过事件冒泡实现的,所谓的事件就是onclick,onmouseover,ondown等等,那么委托呢?委托就是指本来这个事是要你自己做的,但是你却让别人帮 ...

  5. 【转载】socket的半包,粘包与分包的问题

    http://zhaohuiopensource.iteye.com/blog/1541270 首先看两个概念: 短连接: 连接->传输数据->关闭连接    HTTP是无状态的,浏览器和 ...

  6. 串口数据缓存java版

    接触串口很久了,一直以来将都是将串口读取出来的数组转换成字符串通过string.contains()查找是否包涵目标数组,自己感觉low到爆,所以写了一个byte-buffer,测试还是蛮好用的.希望 ...

  7. Python 抽象篇:面向对象之高阶用法

    1.检查继承 如果想要查看一个类是否是另一个类的子类,可以使用内建的issubclass函数 如果想知道已知类的基类,可以直接使用特殊特性__bases__ 同时,使用isinstance方法检查一个 ...

  8. Appium+python 使用 press_keycode 如何输入大写字母

    背景:在做自动化测试项目时,需要在文本框中输入一串数字和字母组合的字符串(注:此页面为webview无法使用send_keys方法) 要使用send_keys方法首先要知道键盘字符对应的数值,这个可以 ...

  9. 使用 Laragon 在 Windows 中快速搭建 Laravel 本地开发环境 (转)

    laravel学院 简介 对于那些使用 Windows 操作系统的同学来说,Homestead 和 LaraDock 虽说支持 Windows 系统,但是对初学者来说,安装配置起来还是有一定复杂度的, ...

  10. go for-range中的循环变量

    测试的时候发现一个有意思的地方,就是go始终利用同一块内存来接收集合中的一个值,只是在每次循环的时候重新赋值而已. package main import (     "fmt" ...