在先前的解决方案中新建一个新的Win32项目FirstD3D11Demo。在写代码之前,我们必须先添加dx11所需要的库。为了链接dx库,右键项目选择属性->vc++目录,在包含目录中添加你所安装的SDK根目录\Include,在库目录中添加 根目录\lib\x86(或x64),在链接器->输入的附加依赖项中添加d3d11.lib、d3dx11.lib、dxerr.lib。

第一次使用d3d,首先应该从初始化开始。

初始化d3d11的步骤主要有以下几个:

1、定义我们要检查的设备类型和特征级别

2、创建d3d设备,渲染环境和交换链

3、创建渲染对象

4、设置视口观察区(ViewPort)

下面将对一些概念和用到的d3d对象和函数作具体说明。

数据格式

D3D应用程序中,无论是纹理图片,还是创建的缓冲区,都有着特定的数据格式。D3D11支持有限的数据格式,以枚举变量形式存在,如下几种:

DXGI_FORMAT_R32G32B32_FLOAT: 3个32位单精度符点数组成,比如用于代表三维空间坐标,以及24位颜色;

DXGI_FORMAT_R16G16B16A16_UNORM: 4个16位数组成,每个成员位于[0,1.0f]之间,UNORM意指:unsigned normalized,即无符号,且归一化的;

DXGI_FORMAT_R32G32_UINT:2个32位数组成,每个成员为无符号整型(unsigned int);

DXGI_FORMAT_R8G8B8A8_UNORM:4个8位数组成,每个成员为[0,1.f]之间;

DXGI_FORMAT_R8G8B8A8_SNORM:4个8位数组成,每个成员为[-1.0f, 1.0f]之间,SNORM意指:signed normalized;

DXGI_FORMAT_R8G8B8A8_SINT:4个8位数组成,每个成员为有符号整型;

特征级别(Feature Level)

特征级别定义了一系列支持不同d3d功能的相应等级,如果一个用户的硬件不支持某一特征等级,程序可以选择较低的等级来运行。

下面是d3d定义的几个不同级别代表不同的d3d版本

typedef enum D3D_FEATURE_LEVEL {
D3D_FEATURE_LEVEL_9_1 = 0x9100,
D3D_FEATURE_LEVEL_9_2 = 0x9200,
D3D_FEATURE_LEVEL_9_3 = 0x9300,
D3D_FEATURE_LEVEL_10_0 = 0xa000,
D3D_FEATURE_LEVEL_10_1 = 0xa100,
D3D_FEATURE_LEVEL_11_0 = 0xb000,
D3D_FEATURE_LEVEL_11_1 = 0xb100,
D3D_FEATURE_LEVEL_12_0 = 0xc000,
D3D_FEATURE_LEVEL_12_1 = 0xc100
} D3D_FEATURE_LEVEL;

在初始化过程中,我们可以提供一组不同的特征等级,程序会从第一个开始逐个检测,碰到第一个合适的来创建设备。因此我们在数组中从高到低放置特征等级提供给初始化程序。

交换链(SwapChain)

为了实现平滑的动画,至少需要两个缓冲区,一个前缓冲区用于显示,一个后缓冲区用于下一帧的绘制,每次绘制完一帧后通过交换前、后缓冲区对应的指针来显示新一帧,并在之前的前缓冲区(当前的后缓冲区)上开始继续绘制下一帧。交换链可以有3个或者更多缓冲区,但一般情况下两个够用了。通常在游戏中,我们有两种颜色缓存,一个主缓存,一个辅助缓存,这就是所谓的前向和后向缓存。主缓存是显示在屏幕上的,辅助缓存则是用于下一帧的绘制。在d3d11中交换链对应的接口为IDXGISwapChain。

深度/模板缓冲区:Depth/Stencil Buffer

深度缓冲区是与交换链缓冲区大小完全一样的一块显存区域,即每个像素在深度缓冲区中对应相应的位置。在渲染管线的最终的混合阶段(Output Merger Stage),每个片(Fragment)都有一个深度值z,与深度缓冲区对应位置上的深度相比较,如果该片段z更小,则绘制该片段,并覆盖当前的尝试值,否则抛弃该片段。该缓冲区主要用于实现投影在屏幕上同一位置、远近不同的物体之间相同的遮挡效果。此外,灵活配置尝试缓冲区,可以实现很多种高级特效。

 多重采样抗锯齿:Multisampling Atialiasing

       针对光栅化显示器抗锯齿的方法有多种,在d3d中采用的多重采样方法。即在每个像素点内部,设置多个采样点,绘制多边形边缘时,针对每个采样点判断是否被多边形覆盖,最终的颜色值从采样点中取均值,以对多边形的边缘进行“模糊化",从而减轻锯齿效果。如下图所示,这是一个4重采样的例子,该像素最终的颜色值是多边形本身颜色值的3/4:

支持d3d11的硬件全部支持4重采样,因此我们在后面的程序中将普遍使用4个采样点。在d3d11中通过结构DXGI_SAMPLE_DESC来设置多重采样,其定义如下:

typedef struct DXGI_SAMPLE_DESC {
UINT Count;
UINT Quality;
} DXGI_SAMPLE_DESC;

D3D11_CREATE_DEVICE_FLAG 枚举类型

typedef enum D3D11_CREATE_DEVICE_FLAG {
D3D11_CREATE_DEVICE_SINGLETHREADED = 0x1,
D3D11_CREATE_DEVICE_DEBUG = 0x2,
D3D11_CREATE_DEVICE_SWITCH_TO_REF = 0x4,
D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x8,
D3D11_CREATE_DEVICE_BGRA_SUPPORT = 0x20,
D3D11_CREATE_DEVICE_DEBUGGABLE = 0x40,
D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY = 0x80,
D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT = 0x100,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT = 0x800
} D3D11_CREATE_DEVICE_FLAG;

D3D11_CREATE_DEVICE_SINGLETHREADED
如果使用该常量,你的应用程序将只可以在一个线程中的调用 Dierct3D 11接口。在默认情况下ID3D11Device
对象是一个安全线程。使用这个标志,你可以增强性能。然而,如果你使用这个标志并且你的应用程序使用
多线程调用Dierct3D 11接口,可能导致不可预期的结果。

D3D11_CREATE_DEVICE_DEBUG
创建一个设备支持调用层。

D3D11_CREATE_DEVICE_SWITCH_TO_REF
注意 这个标志不支持Direct3D 11.

D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
阻止被多线程创建。当使用WARP标志时,WARP和所有光栅不能够被线程调用。这个标志不建议使用。

D3D11_CREATE_DEVICE_BGRA_SUPPORT
Dierct2D需要和Direct3D资源交互。

下面是每个步骤对应的代码:

一、指明驱动设备等级和特征等级

 HRESULT hResult = S_OK;//返回结果

     RECT rc;
GetClientRect(g_hWnd, &rc);//获取窗口客户区大小
UINT width = rc.right - rc.left;
UINT 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);

二、创建设备和交换链

交换链具体定义

typedef struct DXGI_SWAP_CHAIN_DESC {
DXGI_MODE_DESC BufferDesc;
DXGI_SAMPLE_DESC SampleDesc;
DXGI_USAGE BufferUsage;
UINT BufferCount;
HWND OutputWindow;
BOOL Windowed;
DXGI_SWAP_EFFECT SwapEffect;
UINT Flags;
} DXGI_SWAP_CHAIN_DESC;

   BufferDesc指定后缓冲区有关特性;

SampleDesc指定多重采样,前面说过;

BufferUsage,对于交换链,为DXGI_USAGE_RENDER_TARGET_OUTPUT;

BufferCount:我们只创建一个后缓冲区(双缓冲),因此为1;

OutputWindow:指定窗口句柄,Win32程序初始化完创建的主窗口;

Windowed:是否全屏;

DXGI_SWAP_EFFECT:通常为DXGI_SWAP_EFFECT_DISCARD;

Flags:可选

其中DXGI_MODE_DESC定义如下
typedef struct DXGI_MODE_DESC {
UINT Width;
UINT Height;
DXGI_RATIONAL RefreshRate;
DXGI_FORMAT Format;
DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
DXGI_MODE_SCALING Scaling;
} DXGI_MODE_DESC, *LPDXGI_MODE_DESC;

Width、Height为缓冲区大小,一般设为主窗口大小;

Format为缓冲区类型,一般作为渲染对象缓冲区类型为DXGI_FORMAT_R8G8B8A8_UNORM;

其他参数一般为固定的。

交换链的设置

 //交换链
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC));//填充
sd.BufferCount = ; //我们只创建一个后缓冲(双缓冲)因此为1
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 = g_hWnd;
sd.SampleDesc.Count = ; //1重采样
sd.SampleDesc.Quality = ; //采样等级
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //常用参数
sd.Windowed = TRUE; //是否全屏

创建设备及交换链,d3d设备一般都是设备本身和硬件之间的通信,而d3d上下文是一种描述设备如何绘制的渲染设备上下文,这也包含了渲染状态和其他的绘图信息。

而交换链是设备和上下文将要绘制的渲染目标。

D3D11CreateDeviceAndSwapChain函数原型:

HRESULT D3D11CreateDeviceAndSwapChain(
_In_opt_ IDXGIAdapter *pAdapter,
D3D_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
_In_opt_ const D3D_FEATURE_LEVEL *pFeatureLevels,
UINT FeatureLevels,
UINT SDKVersion,
_In_opt_ const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
_Out_opt_ IDXGISwapChain **ppSwapChain,
_Out_opt_ ID3D11Device **ppDevice,
_Out_opt_ D3D_FEATURE_LEVEL *pFeatureLevel,
_Out_opt_ ID3D11DeviceContext **ppImmediateContext
);

pAdapter来选择相应的图形适配器,设为NULL以选择默认的适配器;

DriverType设置驱动类型,一般毫无疑问选择硬件加速,即D3D_DRIVER_TYPE_HARDWARE,此时下一个参数就是NULL;

Flags为可选参数,一般为NULL,可以设为D3D11_CREATE_DEVICE_DEBUG、D3D11_CREATE_DEVICE_SINGLETHREADED,或两者一起,前者让要用于调试时收集信息,后者在确定程序只在单线程下运行时设置为它,可以提高性能;

pFeatureLevels为我们提供给程序的特征等级的一个数组,下一个参数为数组中元素个数;

SDKVersion恒定为D3D11_SDK_VERSION;

ppDevice为设备指针的地址,注意设备是指针类型,这里传递的是指针的地址(二维指针,d3d程序中所有的接口都声明为指针类型!);

pFeatureLevel为最后程序选中的特征等级,我们定义相应的变量,传递它的地址进来;

ppImmediateContext为设备上下文指针的地址,要求同设备指针。

创建设备和交换链的相关代码

 for (UINT driverTypeIndex = ; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
{
g_driverType = driverTypes[driverTypeIndex];
hResult = D3D11CreateDeviceAndSwapChain(
NULL, //默认图形适配器
g_driverType, //驱动类型
NULL, //实现软件渲染设备的动态库句柄,如果使用的驱动设备类型是软件设备则不能为NULL
createDeviceFlags, //创建标志,0用于游戏发布,一般D3D11_CREATE_DEVICE_DEBUG允许我们创建可供调试的设备,在开发中比较有用
featureLevels, //特征等级
numFeatureLevels, //特征等级数量
D3D11_SDK_VERSION, //sdk版本号
&sd,
&g_pSwapChain,
&g_pd3dDevice,
&g_featureLevel,
&g_pImmediateContext
);
if (SUCCEEDED(hResult))
break;
}
if (FAILED(hResult))
return hResult;

三、创建和绑定渲染目标视图

一个渲染目标视图是一个由Output MergerStage读取的D3D资源。交换链的主缓存和辅助缓存为彩色的图像,通过调用交换链中的函数GetBuffer来得到它的指针。得到指针后,然后再通过CreateRenderTargetView函数来创建一个渲染目标视图。创建完渲染目标后,就可以调用Release()释放指针到交换链的后台缓存了。当想渲染一个特定的渲染目标的时,要在绘制函数调用前对它进行设置,这个工作是由OMSetRenderTarget函数完成的。

CreateRenderTargetView函数原型

HRESULT CreateRenderTargetView(
[in] ID3D11Resource *pResource,
[in, optional] const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
[out, optional] ID3D11RenderTargetView **ppRTView
);

pResource为视图对应资源

pDesc为视图描述

ppRTView要创建的视图,是一个指针的地址

这一部分的代码

 //创建渲染目标视图
ID3D11Texture2D *pBackBuffer = NULL;
//获取后缓冲区地址
hResult = g_pSwapChain->GetBuffer(, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hResult))
return hResult; //创建目标视图
hResult = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
//释放后缓冲
pBackBuffer->Release();
if (FAILED(hResult))
return hResult; //绑定到渲染管线
g_pImmediateContext->OMSetRenderTargets(, &g_pRenderTargetView, NULL);

四、创建视口

视口定义了渲染到屏幕上的面积,对于单屏游戏来说一般为全屏的,这样我们设置视口的width和height为交换链对应的width、height就好了;对于分屏游戏,可以创建两个视口

放在屏幕不同位置,以不同玩家的角度来渲染。

D3D11_VIEWPORT定义

typedef struct D3D11_VIEWPORT {
FLOAT TopLeftX; //视口左上角x坐标,一般视口占满屏幕的,所以为0
FLOAT TopLeftY; //y坐标
FLOAT Width; //视口宽度,一般与后缓冲区一致,以保持图像不变形
FLOAT Height; //高度,同上
FLOAT MinDepth; //最小深度值:0.0f
FLOAT MaxDepth; //最大深度值:1.0f
} D3D11_VIEWPORT;

具体代码

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

接下来的Render函数中实现了清除显示屏幕的功能

float ClearColor[] = { 0.5f, 0.1f, 0.2f, 1.0f }; //red,green,blue,alpha
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
g_pSwapChain->Present(, );

下面给出整个工程的代码:

#include <windows.h>
#include <d3d11.h>
#include <DxErr.h>
#include <D3DX11.h> HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;
LPCWSTR g_name = L"FirstD3D11Demo";
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL; //驱动类型
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0; //特征等级
ID3D11Device *g_pd3dDevice = NULL; //设备
ID3D11DeviceContext *g_pImmediateContext = NULL; //设备上下文
IDXGISwapChain *g_pSwapChain = NULL; //交换链
ID3D11RenderTargetView *g_pRenderTargetView = NULL; //要创建的视图 HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Render(); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
if (FAILED(InitWindow(hInstance, nShowCmd)))
return ;
if (FAILED(InitDevice()))
{
CleanupDevice();
return ;
}
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, , ,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else//渲染
{
Render();
}
}
CleanupDevice();
return static_cast<int>(msg.wParam);
} HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbClsExtra = ;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbWndExtra = ;
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wcex.hIconSm = wcex.hIcon;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = g_name;
wcex.lpszMenuName = NULL;
wcex.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wcex))
return E_FAIL; g_hInstance = hInstance;
RECT rc{,,,};
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
g_hWnd = CreateWindowEx(WS_EX_APPWINDOW, g_name, g_name, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, g_hInstance, NULL);
if (!g_hWnd)
return E_FAIL; ShowWindow(g_hWnd, nCmdShow); return S_OK;
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wPararm, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage();
break;
default:
return DefWindowProc(hWnd, message, wPararm, lParam);
}
return ;
} //创建设备及交换链
HRESULT InitDevice()
{
HRESULT hResult = S_OK;//返回结果 RECT rc;
GetClientRect(g_hWnd, &rc);//获取窗口客户区大小
UINT width = rc.right - rc.left;
UINT 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(DXGI_SWAP_CHAIN_DESC));//填充
sd.BufferCount = ; //我们只创建一个后缓冲(双缓冲)因此为1
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 = g_hWnd;
sd.SampleDesc.Count = ; //1重采样
sd.SampleDesc.Quality = ; //采样等级
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //常用参数
sd.Windowed = TRUE; //是否全屏 for (UINT driverTypeIndex = ; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
{
g_driverType = driverTypes[driverTypeIndex];
hResult = D3D11CreateDeviceAndSwapChain(
NULL, //默认图形适配器
g_driverType, //驱动类型
NULL, //实现软件渲染设备的动态库句柄,如果使用的驱动设备类型是软件设备则不能为NULL
createDeviceFlags, //创建标志,0用于游戏发布,一般D3D11_CREATE_DEVICE_DEBUG允许我们创建可供调试的设备,在开发中比较有用
featureLevels, //特征等级
numFeatureLevels, //特征等级数量
D3D11_SDK_VERSION, //sdk版本号
&sd,
&g_pSwapChain,
&g_pd3dDevice,
&g_featureLevel,
&g_pImmediateContext
);
if (SUCCEEDED(hResult))
break;
}
if (FAILED(hResult))
return hResult; //创建渲染目标视图
ID3D11Texture2D *pBackBuffer = NULL;
//获取后缓冲区地址
hResult = g_pSwapChain->GetBuffer(, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hResult))
return hResult; //创建目标视图
hResult = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
//释放后缓冲
pBackBuffer->Release();
if (FAILED(hResult))
return hResult; //绑定到渲染管线
g_pImmediateContext->OMSetRenderTargets(, &g_pRenderTargetView, NULL); //设置viewport
D3D11_VIEWPORT vp;
vp.Height = (FLOAT)height;
vp.Width = (FLOAT)width;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = ;
vp.TopLeftY = ;
g_pImmediateContext->RSSetViewports(, &vp); return S_OK;
} void Render()
{
float ClearColor[] = { 0.5f, 0.1f, 0.2f, 1.0f }; //red,green,blue,alpha
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
g_pSwapChain->Present(, );
} void CleanupDevice()
{
if (g_pImmediateContext)
g_pImmediateContext->ClearState();
if (g_pSwapChain)
g_pSwapChain->Release();
if (g_pRenderTargetView)
g_pRenderTargetView->Release();
if (g_pImmediateContext)
g_pImmediateContext->Release();
if (g_pd3dDevice)
g_pd3dDevice->Release();
}
 

Directx11学习笔记【三】 第一个D3D11程序的更多相关文章

  1. C#.NET学习笔记2---C#.第一个C#程序

    C#.NET学习笔记2---C#.第一个C#程序 技术qq交流群:JavaDream:251572072  教程下载,在线交流:创梦IT社区:www.credream.com 6.第一个C#程序:   ...

  2. Spark学习笔记1——第一个Spark程序:单词数统计

    Spark学习笔记1--第一个Spark程序:单词数统计 笔记摘抄自 [美] Holden Karau 等著的<Spark快速大数据分析> 添加依赖 通过 Maven 添加 Spark-c ...

  3. 【opencv学习笔记五】一个简单程序:图像读取与显示

    今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...

  4. c++学习笔记---04---从另一个小程序接着说

    从另一个小程序接着说 文件I/O 前边我们已经给大家简单介绍和演示过C和C++在终端I/O处理上的异同点. 现在我们接着来研究文件I/O. 编程任务:编写一个文件复制程序,功能实现将一个文件复制到另一 ...

  5. OD学习笔记10:一个VB程序的加密和解密思路

    前边,我们的例子中既有VC++开发的程序,也有Delphi开发的程序,今天我们给大家分析一个VB程序的加密和解密思路. Virtual BASIC是由早期DOS时代的BASIC语言发展而来的可视化编程 ...

  6. DirectX11 学习笔记3 - 创建一个立方体 和 轴

    该方案将在进一步的程序 面向对象. 独立的模型类.更像是一个框架. 其中以超过遇到了一个非常有趣的问题,.获得一晚.我读了好几遍,以找到其他的列子.必须放在某些功能Render里面实时更新,而不是仅仅 ...

  7. 学习笔记_第一个strut程序_之中文乱码,过滤器解决方案及过程总结

    1.  第一次碰到加过滤器的过程,就是在学习struct1的时候,中文乱码 几个需要注意的关键字 2.什么叫package 所谓package就是打包的意思,就是说以下程序都是处于这个包内,所以一开始 ...

  8. OpenGL学习笔记:第一个OpenGL程序

    OpenGL环境搭建参考博客:VS2015下OpenGL库的配置. #include<GL\glew.h> #include<GLTools.h> #include<GL ...

  9. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:第一个Spring程序

    1. 创建项目 在 MyEclipse 中创建 Web 项目 springDemo01,将 Spring 框架所需的 JAR 包复制到项目的 lib 目录中,并将添加到类路径下,添加后的项目如图 2. ...

  10. 【Python学习笔记三】一个简单的python爬虫

    这里写爬虫用的requests插件 1.一般那3.x版本的python安装后都带有相应的安装文件,目录在python安装目录的Scripts中,如下:   2.将scripts的目录配置到环境变量pa ...

随机推荐

  1. VMware Player安装centos

    用VMware Player安装centos 到物理硬盘 想要學Linux,但卻不知道如何弄成雙系統?那就使用用虛擬機器來安裝Linux.使用虛體機器來玩,好處除了好裝之外,也不怕把電腦搞壞,不論你怎 ...

  2. Android入门之简单短信发送器

    效果图: manifest.xml 文件中加入  <uses-permission android:name="android.permission.SEND_SMS"/&g ...

  3. UVA 10140 - Prime Distance(数论)

    10140 - Prime Distance 题目链接 题意:求[l,r]区间内近期和最远的素数对. 思路:素数打表,打到sqrt(Max)就可以,然后利用大的表去筛素数.因为[l, r]最多100W ...

  4. extern int *a与extern int a[]

    extern int *a与int a[] Table of Contents 1. 问题: 2. 解答: 1 问题: 以下的声明取自某个源文件: int a[10]; int *b=a; 但在还有一 ...

  5. cocos2d-x ndk adt mac 路径配置

    export PATH=/bin:/sbin:/usr/local/mysql/bin export PATH=$PATH:/Applications/MacVim-snapshot-68 expor ...

  6. error C2471: 无法更新程序数据库

    这段时间在使用VS做一个项目.在使用过程中,今天遇到了一个问题,也就是题目所说的那样: error C2471: 无法更新程序数据库.之后在网上搜了一下,得到了两种解决方案,两种方案分别如下: (一) ...

  7. WPF界面设计技巧(6)—玩玩数字墨水手绘涂鸦

    原文:WPF界面设计技巧(6)-玩玩数字墨水手绘涂鸦 想让你的程序支持鼠标及手写笔涂鸦吗?只要敲入“<InkCanvas/>”这几个字符,你就会领悟什么叫“很好很强大”,今天我们来做一个手 ...

  8. Libgdx: 将Texturepacker打包的PNG图片还原成一张一张的单个的

    你是否发现用Texturepacker在打包压缩资源文件之后. 把原稿文件弄丢了,可是又要添加新的小png的时候,却无从下手了,本文就是博主在遇到这个问题后百度了非常多方法,可惜仅仅有plist格式的 ...

  9. 自己实现的Boost库中的lexical_cast随意类型转换

    知道了C++的I/O设施之后.这些就变的非常easy了. 假设你常常使用,时间长了就会有感觉.这个事情是多此一举吗?就当是练习吧,知道原理之后,你会认为用起来更舒畅,更喜欢C++了. #include ...

  10. oracle 优化or 更换in、exists、union all几个字眼,测试没有问题!

    oracle 优化or 更换in.exists.union几个字眼.测试没有问题! 根据实际情况选择相应的语句是.假设指数,or全表扫描,in 和not in 应慎用.否则会导致全表扫描.  sele ...