创建一个最小的D3D11实例
我想复习一下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.lib
和d3dx11.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实例相关推荐
- python生成一个窗口_PyQt5创建一个新窗口的实例
更多python教程请到友情连接: 菜鸟教程www.piaodoo.com 人人影视www.sfkyty.com 飞卢小说网www.591319.com 韩剧网www.op-kg.com 兴化论坛ww ...
- android 7 创建文件夹,Android 在 res/layout 文件夹 下创建一个 子文件夹实例
Android 资源文件夹 Layout 文件夹 Layout 文件是存放Android的布局文件的资源文件夹,但是如果你想要在里面创建子文件夹,你会发现xml文件报错. 如何在Layout文件夹下方 ...
- java订单类_基于Java创建一个订单类代码实例
这篇文章主要介绍了基于Java创建一个订单类代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 需求描述 定义一个类,描述订单信息 订单id 订 ...
- 如何创建一个最小的串口、TTY设备包括虚拟控制台,串口以及伪终端设备的驱动程序
来源:LINUX设备驱动程序第三版配套源码 Table of Contents tiny_serial.c tiny_tty.c makefile tiny_serial.c /** Tiny Ser ...
- java订单类_使用Java创建一个订单类代码实例
这篇文章主要简介了使用Java创建一个订单类代码实例,文中通过示例代码简介的非常具体,对大家的学习或者工作具有一定的参考学习网上卖,需要的朋友可以学习下 需求描述 定义一个类,描述订单信息 订单id ...
- 如何创建一个最小的区块链
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 这是我在一个外文网站上看到的一篇博文,作者通过50行代码写出了区块链的简化版本.麻雀虽小,但是五脏俱全.我觉得通过实践, ...
- OpenGL创建一个GLFW窗口的实例
OpenGL创建一个GLFW窗口 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include < ...
- DIRECTDRAW 1:创建一个简单的DIRECTDRAW程序
步骤 1: 创建一个 DirectDraw 对象 要创建一个 DirectDraw 对象的实例,你的应用程序要象 DDEx1 例程中的 doInit 函数那样先使用 DirectDrawCreate ...
- spring boot如何创建一个start_如何创建一个简单的Spring应用?
在这一部分,我们来关注一个使用Spring的DI功能的简单的Spring应用程序.在一个应用程序中使用Spring的DI功能,需要遵循以下步骤. (1)确定应用程序对象及其依赖关系. (2)根据步骤1 ...
最新文章
- 删除Linux的依赖库并进入救援模式恢复
- randperm--生成随机整数排列
- 操作系统——MiniDos
- 【C++深度剖析教程5】C++中类的静态成员函数
- pyqt5使用按钮跳转界面
- amazon实例 更改密钥_如何更改Amazon Echo的警报声音
- 免费 whois 查询 API
- Web前端学习笔记(四)--- CSS卡贴悬停展开效果
- 【前后端常见的登录方式】
- [从头读历史] 第281节 始制文字 世界上的语系及语言
- LCD12864串行驱动程序
- linux重启文件被删除,linux 误删文件恢复方法(debugfs)
- 三星礼包 android,SAMSUNG 三星 Galaxy S8 智能手机 移动合约版(伪开箱)
- 华为浏览器html页样式没了,华为TE40web页面无发登录如何解决?
- UVA 11549 calcular conundrum 计算机老谜题
- scratch实现猫捉老鼠(下)
- 架构进化的本质——用一个例子讲清楚
- 联合培养博士经历对于国内就业有优势吗?
- 《第一堂棒球课》:职业棒球
- 21省人均GDP超过1万美元,北京以19.01万元继续稳居榜首