DirectX9中D3DLOCKED_RECT的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Spring_24/article/details/76927027

1、定义

      在d3d9types.h中,D3DLOCKED_RECT的定义如下:


      其中,pBits为指向矩形的指针,Pitch以字节为单位,表示矩形每一行的长度。
      注意:Pitch有可能比矩形宽度要大且依赖于底层硬件,所以不能单纯的认为
                 Pitch ≠ 矩形宽度 * sizeof(pixelFormat);
      例如:
             矩形大小为320*320,每个像素点为32位,则Pitch ≠ 320 * (32 / 8)。

      《Introduction to 3D Game Programming with DirectX 9.0》书中的解释为如下这样子:
 

2、使用方法

void GenerateTexture()
{//生成红、绿、蓝相间的条纹
	int width = 240, height = 240;

	g_pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_X8R8G8B8,D3DPOOL_MANAGED, &g_pTexture, 0);
	D3DLOCKED_RECT lockrect;
	g_pTexture->LockRect(0, &lockrect, 0, 0);

	char*  nPbit = (char*)lockrect.pBits;
	int nPitch = lockrect.Pitch;
	int stride = nPitch /(4 * 3);//划分为3等份,stride为步长

	DWORD* pwd = (DWORD*)nPbit;
	for(UINT row = 0; row < height; row++)
	{
		for(int col = 0; col < stride; col++)
		{
			pwd[row * nPitch/4 + col] = 0xFFFF0000; 
			pwd[row * nPitch/4 + col + stride] = 0xFF00FF00;
			pwd[row * nPitch/4 + col + 2 * stride] = 0xFF0000FF;
		}
	}
	g_pTexture->UnlockRect(0);
}

  运行效果如下:


3、完整源代码

   
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )
#include <d3dx9math.h>

LPDIRECT3D9             g_pD3D = NULL; 
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; 
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
LPDIRECT3DTEXTURE9  g_pTexture = NULL;

struct CUSTOMVERTEX
{
	FLOAT x, y, z;
	FLOAT tu,tv;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)

HRESULT InitD3D(HWND hWnd)
{
	// Create the D3D object.
	if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
		return E_FAIL;

	// Set up the structure used to create the D3DDevice
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.EnableAutoDepthStencil = TRUE;
    	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	// Create the D3DDevice
	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, &g_pd3dDevice)))
	{
		return E_FAIL;
	}
	return S_OK;
}

void GenerateTexture()
{//生成红、绿、蓝相间的条纹
	int width = 240, height = 240;

	g_pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_X8R8G8B8,D3DPOOL_MANAGED, &g_pTexture, 0);
	D3DLOCKED_RECT lockrect;
	g_pTexture->LockRect(0, &lockrect, 0, 0);

	char*  nPbit = (char*)lockrect.pBits;
	int nPitch = lockrect.Pitch;
	int stride = nPitch /(4 * 3);//划分为3等份,stride为步长

	DWORD* pwd = (DWORD*)nPbit;
	for(UINT row = 0; row < height; row++)
	{
		for(int col = 0; col < stride; col++)
		{
			pwd[row * nPitch/4 + col] = 0xFFFF0000; 
			pwd[row * nPitch/4 + col + stride] = 0xFF00FF00;
			pwd[row * nPitch/4 + col + 2 * stride] = 0xFF0000FF;
		}
	}
	g_pTexture->UnlockRect(0);
}


HRESULT InitGeometry()
{
	CUSTOMVERTEX vertices[] =
    {
		{  -10.0f, -10.0f, 0.0f, 0,1},
		{  -10.0f, 10.0f, 0.0f, 0,0 },
		{  10.0f, 10.0f, 0.0f, 1,0},
		{  10.0f, -10.0f, 0.0f, 1,1 },
	};
	
	// Create the vertex buffer.
	if (FAILED(g_pd3dDevice->CreateVertexBuffer(sizeof(vertices)/sizeof(vertices[0]) * sizeof(CUSTOMVERTEX),
		0, D3DFVF_CUSTOMVERTEX,
		D3DPOOL_DEFAULT, &g_pVB, NULL)))
	{
		return E_FAIL;
	}

	// Fill the vertex buffer.
	VOID* pVertices;
	if (FAILED(g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0)))
		return E_FAIL;
	memcpy(pVertices, (void*)vertices, sizeof(vertices));
	g_pVB->Unlock();
	
	WORD indices[] = {0,1,2,0,2,3};

	if( FAILED( g_pd3dDevice->CreateIndexBuffer( sizeof(indices)/sizeof(indices[0]) * sizeof( WORD ),
                                                  0, D3DFMT_INDEX16,
                                                  D3DPOOL_DEFAULT, &g_pIB, NULL ) ) )
	{
		return E_FAIL;
	}

	VOID* pIndices = NULL;
	if(FAILED(g_pIB->Lock(0, sizeof(indices), (void**)&pIndices,0)))
		return E_FAIL;
	memcpy(pIndices,(VOID*)indices, sizeof(indices));
	g_pIB->Unlock();

	return S_OK;
}


VOID SetupMatrices()
{
	D3DXVECTOR3 vEyePt(0.0f, 0.0f, -30);
	D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
	D3DXMATRIXA16 matView;
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
	g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

	//D3DXMatrixPerspectiveFovLH()函数中的最远、最近距离为相对于视点的距离(即vEyePt中的距离)
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 200.0f);
	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);

}

VOID Cleanup()
{
	if( g_pTexture != NULL )
        g_pTexture->Release();

	if (g_pVB != NULL)
		g_pVB->Release();

	if (g_pd3dDevice != NULL)
		g_pd3dDevice->Release();

	if (g_pD3D != NULL)
		g_pD3D->Release();
}


VOID Render()
{
	g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);

	// Begin the scene
	if (SUCCEEDED(g_pd3dDevice->BeginScene()))
	{
		SetupMatrices();
		GenerateTexture();

		g_pd3dDevice->SetTexture( 0, g_pTexture );
        	g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
        	g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        	g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        	g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

		g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
		g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
		g_pd3dDevice->SetIndices(g_pIB);

		g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
		g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
		g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
		float pointsize = 10;
		g_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&pointsize));
		g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);

		g_pd3dDevice->EndScene();
	}

	// Present the backbuffer contents to the display
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}


INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT)
{
	UNREFERENCED_PARAMETER(hInst);

	// Register the window class
	WNDCLASSEX wc =
	{
		sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		L"D3D Tutorial", NULL
	};
	RegisterClassEx(&wc);

	// Create the application's window
	HWND hWnd = CreateWindow(L"D3D Tutorial", L"D3D : Texture",
		WS_OVERLAPPEDWINDOW, 100, 100, 700, 700,
		NULL, NULL, wc.hInstance, NULL);

	// Initialize Direct3D
	if (SUCCEEDED(InitD3D(hWnd)))
	{
		// Create the scene geometry
		if (SUCCEEDED(InitGeometry()))
		{
			// Show the window
			ShowWindow(hWnd, SW_SHOWDEFAULT);
			UpdateWindow(hWnd);

			// Enter the message loop
			MSG msg;
			ZeroMemory(&msg, sizeof(msg));
			while (msg.message != WM_QUIT)
			{
				if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				else
					Render();
			}
		}
	}

	UnregisterClass(L"D3D Tutorial", wc.hInstance);
	return 0;
}



猜你喜欢

转载自blog.csdn.net/Spring_24/article/details/76927027