D3D11操作

获取交换链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//声明结构体
DXGI_SWAP_CHAIN_DESC scd;
//把结构体用零进行填充
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
//1 创建后缓冲(双缓冲) 缓冲避免图像闪烁
scd.BufferCount = 1;
//将缓冲区格式化 设置颜色格式此处使用RGBA
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
//设置宽
scd.BufferDesc.Width = 1920;
//设置高
scd.BufferDesc.Height = 1080;
//缩放比
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//扫描线
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
//渲染目标输出
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
//允许模式切换
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
//在游戏窗体内部绘制另外一个窗口
scd.OutputWindow = hwindow;
//1重采样
scd.SampleDesc.Count = 1;
//获取进程显示状态判断是否全屏
scd.Windowed = ((GetWindowLongPtr(hwindow, GWL_STYLE) & WS_POPUP) != 0) ? false : true;
//刷新频率
scd.BufferDesc.RefreshRate.Numerator = 144;
//分母 刷新的时候需要做一个除法
scd.BufferDesc.RefreshRate.Denominator = 1;
//采样等级
scd.SampleDesc.Quality = 0;
//常用参数
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

D3D_FEATURE_LEVEL featrueLevel = D3D_FEATURE_LEVEL_11_0;
D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL, &featrueLevel,
1,
D3D11_SDK_VERSION,
&scd, &pSwapChain,
&pDevice, NULL,
&pContext
);

printf("pSwapChain:%X\n", pSwapChain);
printf("pDevice:%X\n", pDevice);
printf("pContext:%X\n", pContext);

D3D9外部绘制

头文件

DirectX.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef DIRECTX_H
#define DIRECTX_H


#include "Main.h"
#include "Drawings.h"


#include <Windows.h>
#include <iostream>


#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")


#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")


extern IDirect3D9Ex* p_Object;
extern IDirect3DDevice9Ex* p_Device;
extern D3DPRESENT_PARAMETERS p_Params;
extern ID3DXFont* pFontSmall;
extern ID3DXLine *pLine;

int DirectXInit(HWND hWnd);
int Render();


#endif

Drawings.h

1
2
3
4
5
6
7
8
9
10
11
12
#include <d3dx9.h>
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

void Box3D(int HeadX, int HeadY, int bottomX, int bottomY, D3DCOLOR Color);
void DrawLine(float x, float y, float x2, float y2, float width, D3DCOLOR color);
void DrawString(const char *fmt, int fontsize, int x, int y, D3DCOLOR color);
void DrawFilledRectangle(float x, float y, float w, float h, D3DCOLOR color);
void DrawBorderBox(int x, int y, int w, int h, int thickness, D3DCOLOR color);

#endif

Main.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef MAIN_H
#define MAIN_H

#include "DirectX.h"

#include <Windows.h>
#include <iostream>

#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")

extern int Width;
extern int Height;
extern char lWindowName[60];
extern HWND hWnd;
extern char tWindowName[60];
extern HWND tWnd;
extern RECT tSize;
extern MSG Message;
extern bool Debug_Border;

LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hSecInstance, LPSTR nCmdLine, INT nCmdShow);


#endif

CPP

DirectX.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "DirectX.h"


IDirect3D9Ex* p_Object = 0;
IDirect3DDevice9Ex* p_Device = 0;
D3DPRESENT_PARAMETERS p_Params;
ID3DXFont* pFontSmall=0;
ID3DXLine *pLine=0;



int DirectXInit(HWND hWnd)
{
if(FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &p_Object)))
exit(1);

ZeroMemory(&p_Params, sizeof(p_Params));
p_Params.Windowed = TRUE;
p_Params.SwapEffect = D3DSWAPEFFECT_DISCARD;
p_Params.hDeviceWindow = hWnd;
p_Params.MultiSampleQuality = D3DMULTISAMPLE_NONE;
p_Params.BackBufferFormat = D3DFMT_A8R8G8B8 ;
p_Params.BackBufferWidth = Width;
p_Params.BackBufferHeight = Height;
p_Params.EnableAutoDepthStencil = TRUE;
p_Params.AutoDepthStencilFormat = D3DFMT_D16;

if (FAILED(p_Object->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &p_Params, 0, &p_Device)))
exit(1);

if (!pLine)
D3DXCreateLine(p_Device, &pLine);

return 0;
}

int Render()
{

//判断窗口是否在最前 如果在最前面才绘制
if (tWnd == GetForegroundWindow())
{
//再次设置透明 清除背景内容
p_Device->Clear(0, 0, D3DCLEAR_TARGET, 0, 1.0f, 0);
//绘制场景
p_Device->BeginScene();

//绘制
DrawLine(400, 400, 500, 500,5, D3DCOLOR_RGBA(255, 0, 0, 255));
DrawFilledRectangle(50, 50, 100, 100, D3DCOLOR_RGBA(255, 0, 0, 255));
DrawString("Simple Text",30 , 10, 10, D3DCOLOR_RGBA(255, 0, 0, 255));
DrawBorderBox(200, 200, 300, 300, 2, D3DCOLOR_RGBA(255, 0, 0, 255));
Box3D(500, 500, 500,600, D3DCOLOR_RGBA(255, 0, 0, 255));

//结束绘制
p_Device->EndScene();
//显示到屏幕上
p_Device->PresentEx(0, 0, 0, 0, 0);
//释放
pFontSmall->Release();
pFontSmall = nullptr;
return 0;
}
//当窗口不在最前面时 只做擦除背景动作
p_Device->Clear(0, 0, D3DCLEAR_TARGET, 0, 1.0f, 0);
p_Device->BeginScene();
p_Device->EndScene();
p_Device->PresentEx(0, 0, 0, 0, 0);
return 0;
}

Drawings.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "Drawings.h"

struct D3DTLVERTEX
{
float x, y, z, rhw;
DWORD color;
};

void Box3D(int HeadX, int HeadY, int bottomX, int bottomY, D3DCOLOR Color)
{
//立体原型
/*float DrawBox1 = 480 / Player_Distance;
float DrawBox2 = 260 / Player_Distance;
float DrawBox3 = 100 / Player_Distance;

DrawLine (pDevice ,bottomX - DrawBox1 ,bottomY ,bottomX + DrawBox1 ,bottomY ,Color );
DrawLine (pDevice ,HeadX - DrawBox1 ,HeadY ,HeadX + DrawBox1 ,HeadY ,Color );
DrawLine (pDevice ,HeadX - DrawBox1 ,HeadY ,bottomX - DrawBox1 ,bottomY ,Color );
DrawLine (pDevice ,HeadX + DrawBox1 ,HeadY ,bottomX + DrawBox1 ,bottomY ,Color );
DrawLine (pDevice ,HeadX - DrawBox2 ,HeadY - DrawBox3 ,bottomX - DrawBox2 ,bottomY - DrawBox3 ,Color );
DrawLine (pDevice ,bottomX - DrawBox1 ,bottomY ,bottomX - DrawBox2 ,bottomY - DrawBox3 ,Color );
DrawLine (pDevice ,HeadX - DrawBox1 ,HeadY ,HeadX - DrawBox2 ,HeadY - DrawBox3 ,Color );
DrawLine (pDevice ,(HeadX + DrawBox1 ) + DrawBox2 ,HeadY - DrawBox3 ,(bottomX + DrawBox1 ) + DrawBox2 ,bottomY - DrawBox3 ,Color );
DrawLine (pDevice ,bottomX + DrawBox1 ,bottomY ,(bottomX + DrawBox1 ) + DrawBox2 ,bottomY - DrawBox3 ,Color );
DrawLine (pDevice ,HeadX + DrawBox1 ,HeadY ,(HeadX + DrawBox1 ) + DrawBox2 ,HeadY - DrawBox3 ,Color );
DrawLine (pDevice ,HeadX - DrawBox2 ,HeadY - DrawBox3 ,(HeadX + DrawBox1 ) + DrawBox2 ,HeadY - DrawBox3 ,Color );
DrawLine (pDevice ,bottomX - DrawBox2 ,bottomY - DrawBox3 ,(bottomX + DrawBox1 ) + DrawBox2 ,bottomY - DrawBox3 ,Color );
*/

DrawLine ( bottomX - 5 ,bottomY ,bottomX + 5 ,bottomY ,1.5,Color);
DrawLine ( HeadX - 5 ,HeadY ,HeadX + 5 ,HeadY ,1.5,Color);
DrawLine ( HeadX - 5 ,HeadY ,bottomX - 5 ,bottomY ,1.5,Color);
DrawLine ( HeadX + 5 ,HeadY ,bottomX + 5 ,bottomY ,1.5,Color);
DrawLine ( HeadX - 7 ,HeadY - 10 ,bottomX - 7 ,bottomY - 10 , 1.5,Color);
DrawLine ( bottomX - 5 ,bottomY ,bottomX - 7 ,bottomY - 10 , 1.5, Color);
DrawLine ( HeadX - 5 ,HeadY ,HeadX - 7 ,HeadY - 10 , 1.5, Color);
DrawLine ( (HeadX + 5 ) + 7 ,HeadY - 10 ,(bottomX + 5) + 7 ,bottomY - 10 , 1.5, Color);
DrawLine ( bottomX + 5 ,bottomY ,(bottomX + 5 ) + 7 ,bottomY - 10 , 1.5, Color);
DrawLine ( HeadX + 5 ,HeadY ,(HeadX + 5 ) + 7 ,HeadY - 10 , 1.5, Color);
DrawLine ( HeadX - 7 ,HeadY - 10 ,(HeadX + 5 ) + 7 ,HeadY - 10 , 1.5, Color);
DrawLine ( bottomX - 7 ,bottomY - 10 ,(bottomX + 5 ) + 7 ,bottomY - 10 , 1.5, Color);
}

void DrawLine(float x, float y, float x2, float y2, float width, D3DCOLOR color)
{

D3DTLVERTEX qV[2] =
{
{ (float)x, (float)y, 0.0f, 1.0f, color },
{ (float)x2, (float)y2, 0.0f, 1.0f, color },
};

p_Device->SetTexture(0, NULL);
p_Device->SetRenderState(D3DRS_LIGHTING, FALSE);
p_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
p_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
p_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
p_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
p_Device->SetRenderState(D3DRS_FOGENABLE, false);
p_Device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
p_Device->DrawPrimitiveUP(D3DPT_LINELIST, 1, qV, sizeof(D3DTLVERTEX));

}

void DrawString(const char *fmt, int fontsize,int x, int y, D3DCOLOR color)
{

D3DXCreateFont(p_Device,fontsize, 0, FW_NORMAL, 1, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &pFontSmall);
RECT FontPos;
FontPos.left = x;
FontPos.top = y;

CHAR buf[124] = { '\0' };
va_list va_alist;
va_start(va_alist, fmt);
vsprintf_s(buf, fmt, va_alist);
va_end(va_alist);

pFontSmall->DrawTextA(0, buf, -1, &FontPos, DT_NOCLIP, color);

}

void DrawFilledRectangle(float x, float y, float w, float h, D3DCOLOR color)
{
D3DRECT rect = { x, y, w, h };
p_Device->Clear(1, &rect, D3DCLEAR_TARGET | D3DCLEAR_TARGET, color, 0, 0);
}


void DrawBorderBox(int x, int y, int w, int h, int thickness, D3DCOLOR color)
{
DrawFilledRectangle(x, y, w, y + thickness, color); // x
DrawFilledRectangle(x, y, x + thickness, h, color); // y
DrawFilledRectangle(x, h, w, h + thickness, color); // w
DrawFilledRectangle(w, y, w + thickness, h + thickness, color); // h
}

Drawings.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "Main.h"


int Width = GetSystemMetrics(SM_CXSCREEN);
int Height = GetSystemMetrics(SM_CYSCREEN);

const MARGINS Margin = { 0, 0, Width, Height };

char lWindowName[60] = " ";
HWND hWnd;
char tWindowName[60] = "WindowName";
HWND tWnd;

RECT tSize;
MSG Message;


LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_PAINT:
if (p_Device == nullptr)
{
return DefWindowProc(hWnd, Message, wParam, lParam);
break;
}
Render();
break;

case WM_CREATE:
//窗口第一次创建成功之前 来到这使用DwmExtendFrameIntoClientArea把创建的窗口铺满整个程序窗口
//Margin 参数设置为 Margin = { 0, 0, Width, Height };
DwmExtendFrameIntoClientArea(hWnd, &Margin);
break;

case WM_DESTROY:
//窗口销毁后得到WM_DESTROY消息 进行释放指针和退出操作
p_Object->Release();
p_Device->Release();
exit(1);
return 0;

default:
//使用DefWindowProc接收处理其他没有得到处理的窗口信息
return DefWindowProc(hWnd, Message, wParam, lParam);
break;
}
return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hSecInstance, LPSTR nCmdLine, INT nCmdShow)
{

//填充DX创建时默认的结构体 声明窗口类
WNDCLASSEX wClass;
wClass.cbClsExtra = NULL;
wClass.cbSize = sizeof(WNDCLASSEX);
wClass.cbWndExtra = NULL;
wClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
wClass.hCursor = LoadCursor(0, IDC_ARROW);
wClass.hIcon = LoadIcon(0, IDI_APPLICATION);
wClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
wClass.hInstance = hInstance;
wClass.lpfnWndProc = WinProc;
wClass.lpszClassName = lWindowName;
wClass.lpszMenuName = lWindowName;
wClass.style = CS_VREDRAW | CS_HREDRAW;

//注册窗口类
if (!RegisterClassEx(&wClass))
exit(1);
//得到程序句柄
tWnd = FindWindow(NULL, tWindowName);
//判断句柄是否为空
if (tWnd)
{
//使用GetWindowRect得到窗口大小
GetWindowRect(tWnd, &tSize);
//计算出窗口宽高
Width = tSize.right - tSize.left;
Height = tSize.bottom - tSize.top;
//使用CreateWindowEx创建一个窗口
//WS_EX_TOPMOST置顶 WS_EX_TRANSPARENT鼠标穿透 WS_EX_LAYERED透明窗口样式 WS_POPUP弹出窗口 WS_EX_TOOLWINDOW隐藏状态栏图标
hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_LAYERED| WS_EX_TOOLWINDOW, lWindowName, lWindowName, WS_POPUP, 1, 1, Width, Height, 0, 0, 0, 0);
/*
BOOL SetLayeredWindowAttributes(
HWND hwnd,
COLORREF crKey,
BYTE bAlpha,
DWORD dwFlags
);
SetLayeredWindowAttributes设置分层窗口透明度
hwnd 分层窗口的句柄。通过使用CreateWindowEx函数创建窗口时指定WS_EX_LAYERED或在创建窗口后通过SetWindowLong设置WS_EX_LAYERED来创建分层窗口。
crKey 一个COLORREF结构,它指定在组成分层窗口时要使用的透明色键。
bAlpha 用于描述分层窗口的不透明度的Alpha值。与BLENDFUNCTION结构的SourceConstantAlpha成员相似。当bAlpha为0时,窗口是完全透明的。当bAlpha为255时,窗口是不透明的。
dwFlags 要采取的行动。此参数可以是以下一个或多个值
LWA_ALPHA 使用bAlpha确定分层窗口的不透明度。
LWA_COLORKEY 使用crKey作为透明颜色。。
*/

SetLayeredWindowAttributes(hWnd, 0, 1.0f, LWA_ALPHA);
SetLayeredWindowAttributes(hWnd, 0, RGB(0, 0, 0), LWA_COLORKEY);
//设置窗口显示状态 SW_SHOW 激活窗口并以其当前大小和位置显示它。
ShowWindow(hWnd, SW_SHOW);
}
//创建DX
DirectXInit(hWnd);



for (;;)
{

tWnd = FindWindow(0, tWindowName);
DWORD Pid;
GetWindowThreadProcessId(tWnd, &Pid);
if (Pid==5664)
{
p_Object->Release();
p_Device->Release();
ExitProcess(0);
}

if (tWnd)
{
//再次获取窗口位置计算窗口大小 以应对窗口移动
GetWindowRect(tWnd, &tSize);
Width = tSize.right - tSize.left;
Height = tSize.bottom - tSize.top;
//如果窗口为WS_BORDER 则进行+-操作
DWORD dwStyle = GetWindowLong(tWnd, GWL_STYLE);
if (dwStyle & WS_BORDER)
{
tSize.top += 23;
Height -= 23;
}
//再移动到对应位置
MoveWindow(hWnd, tSize.left, tSize.top, Width, Height, true);
}
else
{
//如果窗口不存在直接退出程序
p_Object->Release();
p_Device->Release();
exit(1);
}

if(PeekMessage(&Message, hWnd, 0, 0, PM_REMOVE))
{
DispatchMessage(&Message);
TranslateMessage(&Message);
}
Sleep(1);
}

return 0;
}