我想复习一下D3D11的一些基础API,于是翻了翻Microsoft DirectX SDK (June 2010)找到其中一个最简单的D3D11的实例(\Samples\C++\Direct3D11\Tutorials\Tutorial02)。可惜因为SDK版本太旧,安装的教学工程是VS2010的,我尝试升级成VS2017的工程但失败了。于是我决定手动新创建一个工程来跑起来这个教学范例,过程中也抛弃掉了一些比较边缘,不影响效果的内容(其中较为重要的被舍弃的内容是:1.清理掉对象;2.输出shader编译的错误)。

实践

首先,需要安装Microsoft DirectX SDK (June 2010),因为用到了其中的函数。

0.创建一个空工程


之后创建一个cpp文件。

1.目标是创建一个窗口

1.1 入口函数

我们的入口函数是

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)

要确保配置中 链接器 =》系统 =》子系统 设置为窗口,这将表示我们的入口函数是WinMain而不是main

1.2 生成窗口

我们窗口的Handle将存在一个全局变量中:

HWND                    g_hWnd = NULL;

同时,需要一个“窗口过程”来接收Windows发来的消息:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}

然后,就可以初始化窗口了

HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{// Register classWNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)"");wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wcex.lpszMenuName = NULL;wcex.lpszClassName = "TestD3D11WindowClass";wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)"");if (!RegisterClassEx(&wcex))return E_FAIL;// Create windowRECT rc = { 0, 0, WindowWidth, WindowHeight };AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);g_hWnd = CreateWindowA("TestD3D11WindowClass", "TestD3D11Window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,NULL);if (!g_hWnd)return E_FAIL;ShowWindow(g_hWnd, nCmdShow);return S_OK;
}

将入口函数改为:

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{InitWindow(hInstance, nCmdShow);MSG msg = { 0 };while (WM_QUIT != msg.message){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}}return msg.wParam;
}

运行后可看见窗口:

2.目标是初始化D3D11并且以一颜色清理BackBuffer

首先将D3D11相关的头文件配置上:

然后,需要添加lib,
先把lib的路径添加进来

然后依赖d3d11.libd3dx11.lib

下面,写一个新函数InitD3D,他将初始化D3D相关的内容

HRESULT InitD3D()
{HRESULT hr = S_OK;return hr;
}
2.1 尝试创建Device和SwapChain,得到ImmediateContext

首先声明他们的全局变量

ID3D11Device*           g_pd3dDevice = NULL;
ID3D11DeviceContext*    g_pImmediateContext = NULL;
IDXGISwapChain*         g_pSwapChain = NULL;

然后开始写InitD3D中的代码:
列出所有考虑的FeatureLevel:

D3D_FEATURE_LEVEL featureLevels[] =
{D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,
};

列出所有考虑的驱动类型(越靠前越优先考虑)

D3D_DRIVER_TYPE driverTypes[] =
{D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,D3D_DRIVER_TYPE_REFERENCE,
};

创建SwapChain的描述结构体

DXGI_SWAP_CHAIN_DESC swapchainDescription;
ZeroMemory(&swapchainDescription, sizeof(swapchainDescription));
swapchainDescription.BufferCount = 1;
swapchainDescription.BufferDesc.Width = WindowWidth;
swapchainDescription.BufferDesc.Height = WindowHeight;
swapchainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapchainDescription.BufferDesc.RefreshRate.Numerator = 60;
swapchainDescription.BufferDesc.RefreshRate.Denominator = 1;
swapchainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchainDescription.OutputWindow = g_hWnd;
swapchainDescription.SampleDesc.Count = 1;
swapchainDescription.SampleDesc.Quality = 0;
swapchainDescription.Windowed = TRUE;

调用D3D11CreateDeviceAndSwapChain来创建Device和SwapChain,得到ImmediateContext

D3D_DRIVER_TYPE         outDriverType;   //最终决定的DriverType
D3D_FEATURE_LEVEL       outFeatureLevel;//最终决定的FeatureLevel
//按照驱动类型依次尝试创建Device和SwapChain
for (UINT driverTypeIndex = 0; driverTypeIndex < ARRAYSIZE(driverTypes); driverTypeIndex++)
{outDriverType = driverTypes[driverTypeIndex];hr = D3D11CreateDeviceAndSwapChain(NULL, outDriverType, NULL, 0, featureLevels, ARRAYSIZE(featureLevels),D3D11_SDK_VERSION, &swapchainDescription, &g_pSwapChain, &g_pd3dDevice, &outFeatureLevel, &g_pImmediateContext);if (SUCCEEDED(hr))break;
}
if (FAILED(hr))return hr;
2.2创建一个 render target view

先声明全局变量

ID3D11RenderTargetView* g_pRenderTargetView = NULL;

继续写 InitD3D:
从SwapChain那里得到BackBuffer

ID3D11Texture2D* pBackBuffer = NULL;
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))return hr;

调用CreateRenderTargetView创建一个 render target view

hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))return hr;

输出合并阶段(Output-Merger Stage)设置RenderTarget

g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);
2.3

Render函数:
只是以一个浅绿色来清理 back buffer

void Render()
{// 清理 back buffer float ClearColor[4] = { 0.5f, 1.0f, 0.6f, 1.0f }; g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);// Present the information rendered to the back buffer to the front buffer (the screen)g_pSwapChain->Present(0, 0);
}

然后改变我们的入口函数:

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{InitWindow(hInstance, nCmdShow);InitD3D();MSG msg = { 0 };while (WM_QUIT != msg.message){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}else{Render();}}return msg.wParam;
}

运行会看到:

3.目标是画出一个三角形

3.1着色器文件

创建一个着色器文件TestShader.fx,内容很简单:

float4 VS( float4 Pos : POSITION ) : SV_POSITION
{return Pos;
}float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{return float4( 0.8f, 0.7f, 0.9f, 1.0f );
}

顶点着色器只是返回位置,不做任何变换
像素着色器则只输出一个浅紫色

3.2

所需要的的全局变量:

ID3D11VertexShader*     g_pVertexShader = NULL;     //顶点着色器
ID3D11PixelShader*      g_pPixelShader = NULL;     //像素着色器
ID3D11InputLayout*      g_pVertexLayout = NULL;        //顶点输入布局
ID3D11Buffer*           g_pVertexBuffer = NULL;        //顶点缓冲

顶点输入结构:(只有一个“位置”)

struct SimpleVertex
{XMFLOAT3 Pos;
};

设置视窗

D3D11_VIEWPORT vp;
vp.Width = (FLOAT)WindowWidth;
vp.Height = (FLOAT)WindowHeight;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
//光栅化阶段(Rasterize Stage)设置视窗
g_pImmediateContext->RSSetViewports(1, &vp);

创建顶点着色器

//编译顶点着色器
ID3DBlob* pVSBlob = NULL;
hr = D3DX11CompileFromFileA("TestShader.fx", NULL, NULL, "VS", "vs_4_0",0, 0, NULL, &pVSBlob, &pErrorBlob, NULL);
if (FAILED(hr))return hr;
//创建顶点着色器
hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);
if (FAILED(hr))
{pVSBlob->Release();return hr;
}

创建输入布局

//定义顶点输入布局(与SimpleVertex对应)
D3D11_INPUT_ELEMENT_DESC layout[] =
{{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
//创建输入布局
hr = g_pd3dDevice->CreateInputLayout(layout, ARRAYSIZE(layout), pVSBlob->GetBufferPointer(),pVSBlob->GetBufferSize(), &g_pVertexLayout);
pVSBlob->Release();
if (FAILED(hr))return hr;
//输入装配阶段(Input-Assembler Stage)设置输入布局
g_pImmediateContext->IASetInputLayout(g_pVertexLayout);

创建像素着色器

//编译像素着色器
ID3DBlob* pPSBlob = NULL;
hr = D3DX11CompileFromFileA("TestShader.fx", NULL, NULL, "PS", "ps_4_0", 0, 0, NULL, &pPSBlob, &pErrorBlob, NULL);
if (FAILED(hr))return hr;
//创建像素着色器
hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);
pPSBlob->Release();
if (FAILED(hr))return hr;

创建顶点缓冲,只是个简单的三角形

//输入的顶点数据
SimpleVertex vertices[] =
{XMFLOAT3(0.0f, 0.5f, 0.5f),XMFLOAT3(0.5f, -0.5f, 0.5f),XMFLOAT3(-0.5f, -0.5f, 0.5f),
};
//缓冲描述
D3D11_BUFFER_DESC bufferDescription;
ZeroMemory(&bufferDescription, sizeof(bufferDescription));
bufferDescription.Usage = D3D11_USAGE_DEFAULT;
bufferDescription.ByteWidth = sizeof(SimpleVertex) * 3;
bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDescription.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = vertices;
//创建顶点缓冲
hr = g_pd3dDevice->CreateBuffer(&bufferDescription, &InitData, &g_pVertexBuffer);
if (FAILED(hr))return hr;UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
//输入装配阶段(Input-Assembler Stage)设置顶点缓冲
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);//输入装配阶段(Input-Assembler Stage)设置拓扑结构
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
3.3

改变Render函数,中间加上三段:

void Render()
{// 清理 back buffer float ClearColor[4] = { 0.5f, 1.0f, 0.6f, 1.0f }; //浅绿色g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);// 渲染g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);g_pImmediateContext->Draw(3, 0);// Present the information rendered to the back buffer to the front buffer (the screen)g_pSwapChain->Present(0, 0);
}

运行后:

完整代码

#include <windows.h>#include <d3d11.h>
#include <D3DX11.h>
#include <d3dcompiler.h>
#include <xnamath.h>HWND                    g_hWnd = NULL;
ID3D11Device*           g_pd3dDevice = NULL;
ID3D11DeviceContext*    g_pImmediateContext = NULL;
IDXGISwapChain*         g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11VertexShader*     g_pVertexShader = NULL;        //顶点着色器
ID3D11PixelShader*      g_pPixelShader = NULL;     //像素着色器
ID3D11InputLayout*      g_pVertexLayout = NULL;        //顶点输入布局
ID3D11Buffer*           g_pVertexBuffer = NULL;        //顶点缓冲const int WindowWidth = 800;
const int WindowHeight = 600;//顶点输入数据
struct SimpleVertex
{XMFLOAT3 Pos;
};LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{// Register classWNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)"");wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wcex.lpszMenuName = NULL;wcex.lpszClassName = "TestD3D11WindowClass";wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)"");if (!RegisterClassEx(&wcex))return E_FAIL;// Create windowRECT rc = { 0, 0, WindowWidth, WindowHeight };AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);g_hWnd = CreateWindowA("TestD3D11WindowClass", "TestD3D11Window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,NULL);if (!g_hWnd)return E_FAIL;ShowWindow(g_hWnd, nCmdShow);return S_OK;
}HRESULT InitD3D()
{HRESULT hr = S_OK;//所有考虑的FeatureLevelD3D_FEATURE_LEVEL featureLevels[] ={D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_1,D3D_FEATURE_LEVEL_10_0,};//所有考虑的驱动类型(越靠前越优先考虑)D3D_DRIVER_TYPE driverTypes[] ={D3D_DRIVER_TYPE_HARDWARE,D3D_DRIVER_TYPE_WARP,D3D_DRIVER_TYPE_REFERENCE,};//创建SwapChain的描述结构体DXGI_SWAP_CHAIN_DESC swapchainDescription;ZeroMemory(&swapchainDescription, sizeof(swapchainDescription));swapchainDescription.BufferCount = 1;swapchainDescription.BufferDesc.Width = WindowWidth;swapchainDescription.BufferDesc.Height = WindowHeight;swapchainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;swapchainDescription.BufferDesc.RefreshRate.Numerator = 60;swapchainDescription.BufferDesc.RefreshRate.Denominator = 1;swapchainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;swapchainDescription.OutputWindow = g_hWnd;swapchainDescription.SampleDesc.Count = 1;swapchainDescription.SampleDesc.Quality = 0;swapchainDescription.Windowed = TRUE;D3D_DRIVER_TYPE         outDriverType;  //最终决定的DriverTypeD3D_FEATURE_LEVEL       outFeatureLevel;//最终决定的FeatureLevel//按照驱动类型依次尝试创建Device和SwapChainfor (UINT driverTypeIndex = 0; driverTypeIndex < ARRAYSIZE(driverTypes); driverTypeIndex++){outDriverType = driverTypes[driverTypeIndex];hr = D3D11CreateDeviceAndSwapChain(NULL, outDriverType, NULL, 0, featureLevels, ARRAYSIZE(featureLevels),D3D11_SDK_VERSION, &swapchainDescription, &g_pSwapChain, &g_pd3dDevice, &outFeatureLevel, &g_pImmediateContext);if (SUCCEEDED(hr))break;}if (FAILED(hr))return hr;//创建一个 render target viewID3D11Texture2D* pBackBuffer = NULL;hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);if (FAILED(hr))return hr;hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);pBackBuffer->Release();if (FAILED(hr))return hr;//输出合并阶段(Output-Merger Stage)设置RenderTargetg_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);// 设置视窗D3D11_VIEWPORT vp;vp.Width = (FLOAT)WindowWidth;vp.Height = (FLOAT)WindowHeight;vp.MinDepth = 0.0f;vp.MaxDepth = 1.0f;vp.TopLeftX = 0;vp.TopLeftY = 0;//光栅化阶段(Rasterize Stage)设置视窗g_pImmediateContext->RSSetViewports(1, &vp);ID3DBlob* pErrorBlob;//编译顶点着色器ID3DBlob* pVSBlob = NULL;hr = D3DX11CompileFromFileA("TestShader.fx", NULL, NULL, "VS", "vs_4_0",0, 0, NULL, &pVSBlob, &pErrorBlob, NULL);if (FAILED(hr))return hr;//创建顶点着色器hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);if (FAILED(hr)){pVSBlob->Release();return hr;}//定义顶点输入布局(与SimpleVertex对应)D3D11_INPUT_ELEMENT_DESC layout[] ={{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },};//创建输入布局hr = g_pd3dDevice->CreateInputLayout(layout, ARRAYSIZE(layout), pVSBlob->GetBufferPointer(),pVSBlob->GetBufferSize(), &g_pVertexLayout);pVSBlob->Release();if (FAILED(hr))return hr;//输入装配阶段(Input-Assembler Stage)设置输入布局g_pImmediateContext->IASetInputLayout(g_pVertexLayout);//编译像素着色器ID3DBlob* pPSBlob = NULL;hr = D3DX11CompileFromFileA("TestShader.fx", NULL, NULL, "PS", "ps_4_0", 0, 0, NULL, &pPSBlob, &pErrorBlob, NULL);if (FAILED(hr))return hr;//创建像素着色器hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);pPSBlob->Release();if (FAILED(hr))return hr;//输入的顶点数据SimpleVertex vertices[] ={XMFLOAT3(0.0f, 0.5f, 0.5f),XMFLOAT3(0.5f, -0.5f, 0.5f),XMFLOAT3(-0.5f, -0.5f, 0.5f),};//缓冲描述D3D11_BUFFER_DESC bufferDescription;ZeroMemory(&bufferDescription, sizeof(bufferDescription));bufferDescription.Usage = D3D11_USAGE_DEFAULT;bufferDescription.ByteWidth = sizeof(SimpleVertex) * 3;bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;bufferDescription.CPUAccessFlags = 0;D3D11_SUBRESOURCE_DATA InitData;ZeroMemory(&InitData, sizeof(InitData));InitData.pSysMem = vertices;//创建顶点缓冲hr = g_pd3dDevice->CreateBuffer(&bufferDescription, &InitData, &g_pVertexBuffer);if (FAILED(hr))return hr;UINT stride = sizeof(SimpleVertex);UINT offset = 0;//输入装配阶段(Input-Assembler Stage)设置顶点缓冲g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);//输入装配阶段(Input-Assembler Stage)设置拓扑结构g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);return S_OK;
}void Render()
{// 清理 back buffer float ClearColor[4] = { 0.5f, 1.0f, 0.6f, 1.0f }; //浅绿色g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);// 渲染g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);g_pImmediateContext->Draw(3, 0);// Present the information rendered to the back buffer to the front buffer (the screen)g_pSwapChain->Present(0, 0);
}int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{InitWindow(hInstance, nCmdShow);InitD3D();MSG msg = { 0 };while (WM_QUIT != msg.message){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}else{Render();}}return msg.wParam;
}

创建一个最小的D3D11实例相关推荐

  1. python生成一个窗口_PyQt5创建一个新窗口的实例

    更多python教程请到友情连接: 菜鸟教程www.piaodoo.com 人人影视www.sfkyty.com 飞卢小说网www.591319.com 韩剧网www.op-kg.com 兴化论坛ww ...

  2. android 7 创建文件夹,Android 在 res/layout 文件夹 下创建一个 子文件夹实例

    Android 资源文件夹 Layout 文件夹 Layout 文件是存放Android的布局文件的资源文件夹,但是如果你想要在里面创建子文件夹,你会发现xml文件报错. 如何在Layout文件夹下方 ...

  3. java订单类_基于Java创建一个订单类代码实例

    这篇文章主要介绍了基于Java创建一个订单类代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需求描述 定义一个类,描述订单信息 订单id 订 ...

  4. 如何创建一个最小的串口、TTY设备包括虚拟控制台,串口以及伪终端设备的驱动程序

    来源:LINUX设备驱动程序第三版配套源码 Table of Contents tiny_serial.c tiny_tty.c makefile tiny_serial.c /** Tiny Ser ...

  5. java订单类_使用Java创建一个订单类代码实例

    这篇文章主要简介了使用Java创建一个订单类代码实例,文中通过示例代码简介的非常具体,对大家的学习或者工作具有一定的参考学习网上卖,需要的朋友可以学习下 需求描述 定义一个类,描述订单信息 订单id ...

  6. 如何创建一个最小的区块链

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 这是我在一个外文网站上看到的一篇博文,作者通过50行代码写出了区块链的简化版本.麻雀虽小,但是五脏俱全.我觉得通过实践, ...

  7. OpenGL创建一个GLFW窗口的实例

    OpenGL创建一个GLFW窗口 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include < ...

  8. DIRECTDRAW 1:创建一个简单的DIRECTDRAW程序

    步骤 1: 创建一个 DirectDraw 对象 要创建一个 DirectDraw 对象的实例,你的应用程序要象 DDEx1 例程中的 doInit 函数那样先使用 DirectDrawCreate ...

  9. spring boot如何创建一个start_如何创建一个简单的Spring应用?

    在这一部分,我们来关注一个使用Spring的DI功能的简单的Spring应用程序.在一个应用程序中使用Spring的DI功能,需要遵循以下步骤. (1)确定应用程序对象及其依赖关系. (2)根据步骤1 ...

最新文章

  1. 删除Linux的依赖库并进入救援模式恢复
  2. randperm--生成随机整数排列
  3. 操作系统——MiniDos
  4. 【C++深度剖析教程5】C++中类的静态成员函数
  5. pyqt5使用按钮跳转界面
  6. amazon实例 更改密钥_如何更改Amazon Echo的警报声音
  7. 免费 whois 查询 API
  8. Web前端学习笔记(四)--- CSS卡贴悬停展开效果
  9. 【前后端常见的登录方式】
  10. [从头读历史] 第281节 始制文字 世界上的语系及语言
  11. LCD12864串行驱动程序
  12. linux重启文件被删除,linux 误删文件恢复方法(debugfs)
  13. 三星礼包 android,SAMSUNG 三星 Galaxy S8 智能手机 移动合约版(伪开箱)
  14. 华为浏览器html页样式没了,华为TE40web页面无发登录如何解决?
  15. UVA 11549 calcular conundrum 计算机老谜题
  16. scratch实现猫捉老鼠(下)
  17. 架构进化的本质——用一个例子讲清楚
  18. 联合培养博士经历对于国内就业有优势吗?
  19. 《第一堂棒球课》:职业棒球
  20. 21省人均GDP超过1万美元,北京以19.01万元继续稳居榜首

热门文章

  1. Python3绘制分形图像
  2. 微信、QQ自动抢红包外挂(绿色、无广告--附源码)
  3. 机器人碰撞检测几何模型设计
  4. 《第3次机器人大战α》民间汉化版曝光
  5. android 仿脉搏柱动画,Android属性动画学习笔记
  6. 【语音识别】基于BP神经网络实现语音特征信号分类附matlab代码
  7. 撞上元宇宙冷门新职业 我变年入百万打工人
  8. 如何成为邮件营销“标题党”?
  9. 工商注册身份验证 v1.0.1
  10. 欧拉角与万向节死锁(图文版)