• DirectX11 学习笔记4



    本程序主要由5个文件组成。1个CPP 4个H文件  本来H文件能够分为4个CPP4个H,可是感觉太多了,就写到一起了

    XMain 

    这个文件就是windows程序的入口函数

    <span style="font-size:14px;">//入口
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow) 
    {
    
    	XWindow *xwindow=new XWindow;
    	xwindow->init(); //初始化
    	xwindow->close();
    	delete xwindow;
    	return 0; 
    }</span>

    接下来就是进入XWindow.h 

    XWindow.h

    首先是init()

    xwidth=500;
    	xheight=400;
    	x_input=new XInput;
    	x_graphics=new XGraphics;
    	
    	//创建窗体
    	initWindows(xwidth,xheight,L"Engine");
    	//初始化键盘
    	x_input->init();
    	//初始化渲染
    	x_graphics->init(xwidth,xheight,m_hwnd);
    
    
    	//消息循环
    	runWindows();
    	//关闭窗体
    	closeWindows();
    主要就是创建了 窗体,键初始化,渲染初始化。 然后就能够開始我们的消息循环了。

    窗体初始化学过windows编程的就知道比較简单。然后x_input后面讲。

    唯一与Directx相关的就是消息循环和渲染了。

    当中消息循环:

    MSG msg; 
    	// 初始化消息结构. 
    	ZeroMemory(&msg, sizeof(MSG));
    	// 循环进行消息处理
    	while(!Xexit) 
    	{ 
    		// 处理windows消息. 
    		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    		{ 
    			TranslateMessage(&msg); 
    			DispatchMessage(&msg); 
    		}
    		// 接收到WM_QUIT消息,退出程序. 
    		if(msg.message == WM_QUIT) 
    		{ 
    			Xexit=true;
    		} 
    		else 
    		{ 
    			//渲染
    			Xexit=!frame();
    		}
    
    	}

    加了一个frame函数, 意思就是除了接受windows的正常消息之外。还不断的循环着一个函数frame. 

    这个frame就是渲染有关的啦。

    bool XWindow::frame()
    {
    	//推断是否按下ESC键
    	if(x_input->isKeyDown(VK_ESCAPE))
    		return false;
    	//開始渲染
    	return x_graphics->frame();
    }

    bool XGraphics::frame() 
    {
    	bool hr=render();
    	return hr; 
    }
    
    bool XGraphics::render() 
    {
    	x_d3d->begin(0.0f,0.0f,0.5f,1.0f);//蓝色
    	x_d3d->end();
    	return true; 
    }
    

    如上面一层一层的调用。

    事实上终于就是绘制了一个蓝色的背景。之所以写这么多层,而不在一个程序里2行代码搞定,是由于之后的project越来越大,所有放一个文件。会很难分析其逻辑,并且很难改动。

    XGraphics

    以后主要代码就是写在这个类里面了。如今还是空空的。

    XD3Device

    这个类就是做这个框架的意义了。

    里面的init() 初始化了一堆非常复杂,非常烦躁的。  设备链,深度模板缓冲,各种状态绑定等等。都是一次性的。

    后面仅仅须要改改參数即可。所以把它隔离到这个类。

    仅仅要在用的时候轻轻调用一个函数就能够了

    bool XGraphics:: init(int screenWidth, int screenHeight, HWND hwnd) 
    {
    	x_d3d=new XD3Device;
    	bool hr=x_d3d->init(screenWidth,screenHeight,VSYNC_ENABLED,hwnd,FULL_SCREEN,SCREEN_DEPTH,SCREEN_NEAR);
    	if(!hr)
    	{
    		MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK); 
    		return false; 
    	}
    	return true; 
    }


    所有代码

    XGraphics.h

    效果

    #pragma once
    
    #include <windows.h>
    #include "XD3Device.h"
    ///////////// 
    // GLOBALS // 
    ///////////// 
    const bool  FULL_SCREEN = false; //是否全屏 
    const bool  VSYNC_ENABLED = true; //是否垂直同步 
    const float SCREEN_DEPTH = 1000.0f; //深度,远点 
    const float SCREEN_NEAR = 0.1f; //深度,近点
    
    class XGraphics 
    { 
    public: 
    	bool init(int, int, HWND); //初始化渲染设备
    	void close(); 
    	bool frame();
    
    private: 
    	bool render(); 
    private:
    	XD3Device *x_d3d;
    };
    
    bool XGraphics:: init(int screenWidth, int screenHeight, HWND hwnd) 
    {
    	x_d3d=new XD3Device;
    	bool hr=x_d3d->init(screenWidth,screenHeight,VSYNC_ENABLED,hwnd,FULL_SCREEN,SCREEN_DEPTH,SCREEN_NEAR);
    	if(!hr)
    	{
    		MessageBox(hwnd, L"Could not initialize Direct3D", L"Error", MB_OK); 
    		return false; 
    	}
    	return true; 
    }
    
    void XGraphics::close() 
    {
    	if(x_d3d)
    	{
    		x_d3d->close();
    		delete x_d3d;
    		x_d3d=0;
    	}
    }
    
    bool XGraphics::frame() 
    {
    	bool hr=render();
    	return hr; 
    }
    
    
    bool XGraphics::render() 
    {
    	x_d3d->begin(0.0f,0.0f,0.5f,1.0f);//蓝色
    	x_d3d->end();
    	return true; 
    }
    

    XWindows.h

    #pragma once 
    //定义该宏可以降低windows头文件的大小,使编译器不编译一些不必要的文件,加快编译时间 
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    #include "XGraphics.h"
    #include "XInput.h"
    //退出
    static bool Xexit=false;
    //全屏
    static bool fullScreen=false;
    class XWindow
    {
    private:
    	//窗体类名字
    	LPCWSTR m_applicationName;
    	//实例句柄
    	HINSTANCE m_hinstance;
    	//窗体句柄
    	HWND m_hwnd;
    	int xwidth,xheight;
    	//按键类
    	XInput * x_input;
    	//图形类
    	XGraphics * x_graphics;
    private:
    	//初始化窗体
    	void initWindows(int& screenWidth, int& screenHeight,LPCWSTR m_applicationName);
    	//关闭窗体
    	void closeWindows();
    	//消息循环
    	void runWindows();
    	
    public:
    	//初始化全局
    	virtual void init();
    	//渲染
    	virtual bool frame();
    	//退出
    	virtual void close();
    	//消息函数
    	LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM); 
    };
    //消息循环回调函数
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    static XWindow * appXWindow=NULL;
    void XWindow::close()
    {
    	if(x_input)
    	{
    		delete x_input;
    		x_input=NULL;
    	}
    	if(x_graphics)
    	{
    		x_graphics->close();
    		delete x_graphics;
    		x_graphics=NULL;
    	}
    }
    void XWindow::init()
    {
    	xwidth=500;
    	xheight=400;
    	x_input=new XInput;
    	x_graphics=new XGraphics;
    	
    	//创建窗体
    	initWindows(xwidth,xheight,L"Engine");
    	//初始化键盘
    	x_input->init();
    	//初始化渲染
    	x_graphics->init(xwidth,xheight,m_hwnd);
    
    
    	//消息循环
    	runWindows();
    	//关闭窗体
    	closeWindows();
    }
    bool XWindow::frame()
    {
    	//推断是否按下ESC键
    	if(x_input->isKeyDown(VK_ESCAPE))
    		return false;
    	//開始渲染
    	return x_graphics->frame();
    }
    void XWindow::initWindows(int& screenWidth, int& screenHeight,LPCWSTR m_applicationName)
    {
    	WNDCLASSEX wc; 
    	DEVMODE dmScreenSettings; 
    	int posX, posY;
    	this->m_applicationName=m_applicationName;
    	// 得到应用程序实例句柄 
    	m_hinstance = GetModuleHandle(NULL);
    	appXWindow=this;
    	// 设置窗体类參数. 
    	wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
    
    	wc.lpfnWndProc   = WndProc; //指定回调函数 
    	wc.cbClsExtra    = 0; 
    	wc.cbWndExtra    = 0; 
    	wc.hInstance     = m_hinstance; 
    	wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); 
    	wc.hIconSm       = wc.hIcon; 
    	wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
    	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //默认黑色窗体黑色背景 
    	wc.lpszMenuName  = NULL; 
    	wc.lpszClassName = m_applicationName; 
    	wc.cbSize        = sizeof(WNDCLASSEX);
    
    	// 注冊窗体类 
    	RegisterClassEx(&wc);
    
    	// 依据是否全屏设置不同的分辨率. 
    	if(fullScreen) 
    	{ 
    		// 得到windows桌面分辨率 
    		screenWidth  = GetSystemMetrics(SM_CXSCREEN); 
    		screenHeight = GetSystemMetrics(SM_CYSCREEN);
    		//全屏模式下。设置窗体大小为windows桌面分辨率. 
    		memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); 
    		dmScreenSettings.dmSize       = sizeof(dmScreenSettings); 
    		dmScreenSettings.dmPelsWidth  = (unsigned long)screenWidth; 
    		dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight; 
    		dmScreenSettings.dmBitsPerPel = 32;            
    		dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
    
    		// 暂时设置显示设备为全屏模式,注意:应用程序退出时候。将恢复系统默认设置。

    ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); // 设置窗体的左上角坐标位置为(0,0). posX = posY = 0; } else { // 窗体左上角坐标位置,posX, posY posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2; posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2; } // 全屏和窗体使用不同的參数. if( fullScreen) { m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); } else { m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_OVERLAPPEDWINDOW, posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); } // 显示窗体并设置其为焦点. ShowWindow(m_hwnd, SW_SHOW); SetForegroundWindow(m_hwnd); SetFocus(m_hwnd); // 隐藏鼠标. //ShowCursor(false); } void XWindow::runWindows() { MSG msg; // 初始化消息结构. ZeroMemory(&msg, sizeof(MSG)); // 循环进行消息处理 while(!Xexit) { // 处理windows消息. if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } // 接收到WM_QUIT消息,退出程序. if(msg.message == WM_QUIT) { Xexit=true; } else { //渲染 Xexit=!frame(); } } return; } LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) { switch(umessage) { // 窗体销毁消息. case WM_DESTROY: case WM_CLOSE: { PostQuitMessage(0); return 0; } break; //MessageHandle过程处理其他全部消息. default: { return appXWindow->MessageHandler(hwnd, umessage, wparam, lparam); } break; } } LRESULT CALLBACK XWindow::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { switch(umsg) { // 检測按键消息. case WM_KEYDOWN: x_input->keyDown(wparam); break; case WM_KEYUP: x_input->keyUp(wparam); break; //不论什么其他消息发送到windows缺省处理. default: { return DefWindowProc(hwnd, umsg, wparam, lparam); } } return 0; } void XWindow::closeWindows() { //显示光标. //ShowCursor(true); // 恢复默认显示设置. if(fullScreen) { ChangeDisplaySettings(NULL, 0); } //释放窗体句柄. DestroyWindow(m_hwnd); m_hwnd = NULL; // 释放应用程序实例. UnregisterClass(m_applicationName, m_hinstance); m_hinstance = NULL; appXWindow=NULL; return; }


    XInput.h

    #pragma once
    class XInput
    {
    public:
    	void init();
    	void keyDown(unsigned int);
    	void keyUp(unsigned int);
    	bool isKeyDown(unsigned int);
    private:
    	bool x_keys[256];
    
    };
    void XInput::init()
    {
    	int i;
    
    	// 初始全部的键都是非按下状态. 
    	for(i=0; i<256; i++) 
    	{ 
    		x_keys[i] = false; 
    	}
    
    	return; 
    }
    void XInput::keyDown(unsigned int input) 
    { 
    	//键被按下. 
    	x_keys[input] = true; 
    	return; 
    }
    void XInput::keyUp(unsigned int input) 
    { 
    	//键被按下. 
    	x_keys[input] = false; 
    	return; 
    }
    bool XInput::isKeyDown(unsigned int key) 
    { 
    	// 推断键是否被按下? 
    	return x_keys[key]; 
    }
    

    XMain.cpp

    #include "XWindow.h"
    //入口
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow) 
    {
    
    	XWindow *xwindow=new XWindow;
    	xwindow->init(); //初始化
    	xwindow->close();
    	delete xwindow;
    	return 0; 
    }
    

    XD3Device.h


    </pre><pre name="code" class="cpp">#pragma once
    #pragma comment(lib, "dxgi.lib")
    #pragma comment(lib, "d3d11.lib")
    #pragma comment(lib, "d3dx11.lib")
    #pragma comment(lib, "d3dx10.lib")
    #include <dxgi.h>
    #include <d3dcommon.h>
    #include <d3d11.h>
    #include <d3dx10math.h>
    #include <xnamath.h>
    class XD3Device
    {
    public:
    	XD3Device();
    	//3D设备全部初始化
    	bool init(int, int, bool, HWND, bool, float, float);
    	//关闭设备
    	void close();
    	//開始渲染设备
    	void begin(float, float, float, float);
    	//显示到前景
    	void end();
    
    public:
    	bool m_vsync_enabled; //是否启用垂直同步
    	IDXGISwapChain* m_swapChain; //交换链对象
    	ID3D11Device* m_device;  //设备对象
    	ID3D11DeviceContext* m_deviceContext; //设备上下文对象
    	ID3D11RenderTargetView* m_renderTargetView; //渲染目标视图
    	ID3D11Texture2D* m_depthStencilBuffer; //深度模板缓冲
    	ID3D11DepthStencilState* m_depthStencilState; //深度磨成状态
    	ID3D11DepthStencilView* m_depthStencilView; //深度目标视图
    	ID3D11RasterizerState* m_rasterState; //光栅化状态
    	D3DXMATRIX m_projectionMatrix; //投影矩阵
    	D3DXMATRIX m_worldMatrix;//世界坐标系矩阵
    	D3DXMATRIX m_orthoMatrix;//正交投影矩阵
    };
    void XD3Device::begin(float red, float green, float blue, float alpha)
    {
    	float color[]={red,green,blue,alpha};
    	//清除后缓冲.
    	m_deviceContext->ClearRenderTargetView(m_renderTargetView, color);
    
    	//清除深度缓冲.
    	m_deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
    
    }
    void XD3Device::end()
    {
    	//渲染完毕后。把后缓冲内容present到前缓冲
    	if(m_vsync_enabled)
    	{
    		// 锁定屏幕刷新率.
    		m_swapChain->Present(1, 0);
    	}
    	else
    	{
    		// 尽可能快的present后缓冲.
    		m_swapChain->Present(0, 0);
    	}
    
    }
    void XD3Device::close()
    {
    	// 释放交换链资源前。先设置为窗体模式,否则可能会产生异常.
    	if(m_swapChain)
    	{
    		m_swapChain->SetFullscreenState(false, NULL);
    	}
    
    	if(m_rasterState)
    	{
    		m_rasterState->Release();
    		m_rasterState = 0;
    	}
    
    	if(m_depthStencilView)
    	{
    		m_depthStencilView->Release();
    		m_depthStencilView = 0;
    	}
    
    	if(m_depthStencilState)
    	{
    		m_depthStencilState->Release();
    		m_depthStencilState = 0;
    	}
    
    	if(m_depthStencilBuffer)
    	{
    		m_depthStencilBuffer->Release();
    		m_depthStencilBuffer = 0;
    	}
    
    	if(m_renderTargetView)
    	{
    		m_renderTargetView->Release();
    		m_renderTargetView = 0;
    	}
    
    	if(m_deviceContext)
    	{
    		m_deviceContext->Release();
    		m_deviceContext = 0;
    	}
    
    	if(m_device)
    	{
    		m_device->Release();
    		m_device = 0;
    	}
    
    	if(m_swapChain)
    	{
    		m_swapChain->Release();
    		m_swapChain = 0;
    	}
    
    }
    XD3Device::XD3Device()
    {
    	m_swapChain = 0;
    	m_device = 0;
    	m_deviceContext = 0;
    	m_renderTargetView = 0;
    	m_depthStencilBuffer = 0;
    	m_depthStencilState = 0;
    	m_depthStencilView = 0;
    	m_rasterState = 0;
    }
    //Initialize函数包括完毕D3D设置的全部代码。
    bool XD3Device::init(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, 
    						  float screenDepth, float screenNear)
    {
    	HRESULT result;
    	IDXGIFactory* factory;
    	IDXGIAdapter* adapter;
    	IDXGIOutput* adapterOutput;
    	unsigned int numModes, i, stringLength;
    	DXGI_MODE_DESC* displayModeList;
    	DXGI_ADAPTER_DESC adapterDesc;
    	int error;
    	DXGI_SWAP_CHAIN_DESC swapChainDesc;
    	D3D_FEATURE_LEVEL featureLevel;
    	ID3D11Texture2D* backBufferPtr;
    	D3D11_TEXTURE2D_DESC depthBufferDesc;
    	D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
    	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
    	D3D11_RASTERIZER_DESC rasterDesc;
    	D3D11_VIEWPORT viewport;
    	float fieldOfView, screenAspect;
    
    
    	// 保存垂直同步设置
    	m_vsync_enabled = vsync;
    
    	// 初始化交换链描写叙述
    	ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
    	//MessageBox(hwnd, L"Could 2", L"Error", MB_OK); 
    	// 用1个后缓冲
    	swapChainDesc.BufferCount = 1;
    
    	//帧缓冲的大小和应用程序窗体大小相等.
    	swapChainDesc.BufferDesc.Width = screenWidth;
    	swapChainDesc.BufferDesc.Height = screenHeight;
    
    	// 后缓冲的surface的格式为DXGI_FORMAT_R8G8B8A8_UNORM.
    	// surface的每一个像素用4个无符号的8bit[映射到0-1]来表示。

    NORM表示归一化。 swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // 假设使用垂直同步,设置后缓冲的刷新率。. //刷新率就是一秒钟把后缓冲内容在屏幕上画出的次数。

    //假设开启垂直同步,则锁定刷新率,则fps是固定的 if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // 设置后缓冲的用途 // 我们的渲染目标缓冲为后缓冲。 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // 后缓冲输出的窗体句柄. swapChainDesc.OutputWindow = hwnd; // 不使用多重採样 swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // 设置全屏或者窗体模式. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } //MessageBox(hwnd, L"Could 1", L"Error", MB_OK); // 设定扫描线ordering以及缩放为unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // 后缓冲内容呈现到屏幕后。放弃其内容 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //不设置标志 swapChainDesc.Flags = 0; // 设置feature level为D3D11 // 假设显卡不支持D3D11,我们可以通过设置这个參数,使用D3D10,或者9. //featureLevel = D3D_FEATURE_LEVEL_10_1; D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); // 创建交换链,设备以及设备上下文. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); //MessageBox(hwnd, L"Could 1", L"Error", MB_OK); if(FAILED(result)) { return false; } // 得到交换链中的后缓冲指针. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } // 用后缓冲创建渲染目标视图. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } //释放后缓冲.(引用计数减1) backBufferPtr->Release(); backBufferPtr = 0; // 初始化深度缓冲描写叙述. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //设置深度缓冲描写叙述 depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1;//对于深度缓冲为1 depthBufferDesc.ArraySize = 1;//对于深度缓冲为1。对于纹理,这2个參数有很多其它用途 depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // 创建深度缓冲. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } // 初始化深度模版状态描写叙述. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // 设置深度模版状态描写叙述. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;//D3D11_DEPTH_WRITE_MASK_ZERO禁止写深度缓冲 depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // 对于front face 像素使用的模版操作操作. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 对于back face像素使用的模版操作模式. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 创建深度模版状态,使其生效 result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } // 设置深度模版状态. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // 初始化深度模版视图. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // 设置深度模版视图描写叙述. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // 创建深度模版视图. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // 绑定渲染目标视图和深度缓冲到渲染管线. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // 设置光栅化描写叙述,指定多边形怎样被渲染. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // 创建光栅化状态 result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } //设置光栅化状态,使其生效 m_deviceContext->RSSetState(m_rasterState); // 设置视口,显示全部后缓冲内容 viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // 创建视口 m_deviceContext->RSSetViewports(1, &viewport); // 设置透视投影矩阵 fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // 创建透视投影矩阵. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); //初始化world矩阵为单位矩阵. //该矩阵实现局部坐标到世界坐标的转换 D3DXMatrixIdentity(&m_worldMatrix); // 创建正交投影矩阵,主要用来实施2D渲染. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }




  • 相关阅读:
    大数据学习路线图 让你精准掌握大数据技术学习
    在AI人工智能中如何巧妙学习大数据编程,成为五十万年薪的佼佼者
    大数据学习之Hadoop快速入门
    大数据学习|小白学习大数据需要满足这六个条件你就能学好大数据
    大数据学习路线(自己制定,从零开始)
    大数据学习之路(跟着大神学习一波)
    为什么这么多人学习大数据?新手该如何上手大数据?
    大数据学习路线图 让你精准掌握大数据技术学习?
    [监督学习]GDA 高斯判别分析
    The Josephus problem
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6911568.html
Copyright © 2020-2023  润新知