纹理寻址DirectX入门 (8) TextureAddressMode

PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!

//-----------------------------------------------------------------------------
// File: TextureAddressMode.cpp
// Path: G:\Projects\vs2012\DirectTest\TextureAddressMode
// Desc: 纹理寻址模式demo
//
// Copyright (c) Jncpp. All rights reserved.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------
// D3D应用程序可认为任何图元的任何顶点指定纹理坐标,平日使用的u.v纹理坐标的取值范围是[0.0, 1.0]
// 但现实,也可以设置该范围之外的坐标值,失掉纹理映射的特殊效果
// 通过设置纹理寻址模式,可控制D3D如何处理[0.0, 1.0]之外的纹理坐标值
// D3D定义了四种纹理寻址模式:
//	1. 重叠纹理寻址(D3D默许的寻址模式)
//	2. 镜像纹理寻址
//	3. 夹取纹理寻址
//	4. 边框颜色纹理寻址
//-----------------------------------------------------------------

#include<d3dx9.h>
#include "resource.h"

//-----------------------------------------------------------------
// Global Variable
//-----------------------------------------------------------------
LPDIRECT3D9             g_pD3D                  = NULL;
LPDIRECT3DDEVICE9       g_pd3dDevice            = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuf            = NULL;
LPDIRECT3DTEXTURE9      g_pTexture1             = NULL;				//两个不同位图对应的纹理对象
LPDIRECT3DTEXTURE9      g_pTexture2             = NULL;
float					g_fDistance				= -10;		//摄像机距离图形的距离,用于放大缩小
int						g_iTexAddressMode		= 1;

struct CUSTOMVERTEX 
{
	FLOAT x, y, z;		//顶点坐标
	FLOAT u, v;			//顶点纹理坐标
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)			//灵活顶点格式,包含未经坐标变换的顶点坐标格式和含一个纹理坐标格式的顶点数据

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: 设置变换矩阵
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
	//创立并设置世界矩阵
	D3DXMATRIXA16 matWorld;
	D3DXMatrixIdentity(&matWorld);							//单位化世界矩阵
	g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);		//设置世界矩阵

	//创立并设置视察矩阵
	D3DXVECTOR3 vEyePt(0.0f, 0.0f, g_fDistance);
	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);		//设置视察矩阵

	//创立并设置投影矩阵
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f);		//基于左手生成投影矩阵
	g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);		//设置投影矩阵
}


//-----------------------------------------------------------------------------
// Name: Init3D()
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D(HWND hWnd)
{
	if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
		hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, &g_pd3dDevice)))
	{
		return E_FAIL;
	}

	//关闭光照处理,D3D默许已启用光照处理
	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InitGriphics()
// Desc: 创立纹理对象和场景图形
//-----------------------------------------------------------------------------
HRESULT InitGriphics()
{
	//创立纹理对象
	if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, L"texture1.bmp", &g_pTexture1)))
	{
		MessageBox(NULL, L"创立纹理失败", L"DirectTest 07 : TextureBase", MB_OK);
		return E_FAIL;
	}
	if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, L"texture2.bmp", &g_pTexture2)))
	{
		MessageBox(NULL, L"创立纹理失败", L"DirectTest 07 : TextureBase", MB_OK);
		return E_FAIL;
	}

	//顶点数据
	CUSTOMVERTEX vertices[] = 
	{
		//纹理坐标的(1,1)是对应的长宽的像素比
		{-3, -3, 0.0f, 0.0f, 3.0f},			//设置3*3倍图形大小
		{-3,  3, 0.0f, 0.0f, 0.0f},
		{ 3, -3, 0.0f, 3.0f, 3.0f},
		{ 3,  3, 0.0f, 3.0f, 0.0f},
	};
	//创立顶点缓冲区
	if (FAILED(g_pd3dDevice->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
		D3DPOOL_MANAGED, &g_pVertexBuf, NULL)))
	{
		return E_FAIL;
	}

	//填入顶点缓冲区
	VOID *pVertices;
	if(FAILED(g_pVertexBuf->Lock(0, sizeof(vertices), (void **)&pVertices, 0)))
	{
		return E_FAIL;
	}
	memcpy(pVertices, vertices, sizeof(vertices));
	g_pVertexBuf->Unlock();

	return S_OK;
}

//-----------------------------------------------------------------------------
// Name: SetTexture()
// Desc: 根据键盘按键切换纹理寻址模式
//-----------------------------------------------------------------------------
void SetTexture()
{
	switch(g_iTexAddressMode)
	{
	case 1:				//重叠纹理寻址
		g_pd3dDevice->SetTexture(0, g_pTexture1);
		//设置纹理寻址模式
		//SetSamplerState()函数用于设置纹理寻址模式
			//参数1. 指定须要设置属性的纹理层序号
		//	参数2. 指定对u方向还是v方向设置纹理寻址模式
		//	参数3. 指定纹理寻址模式
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);	//设置u方向上的纹理寻址
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);	//设置v方向上的纹理寻址
		break;
	case 2:				//镜像纹理寻址
		g_pd3dDevice->SetTexture(0, g_pTexture1);
		//设置纹理寻址模式
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
		break;
	case 3:				//夹取纹理寻址
		g_pd3dDevice->SetTexture(0, g_pTexture2);
		//设置纹理寻址模式
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
		break;
	case 4:				//边框颜色纹理寻址
		g_pd3dDevice->SetTexture(0, g_pTexture2);
		//设置边框颜色为红色
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0xffff0000);
		//设置纹理寻址模式
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
		g_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
		break;
	}
}

//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 释放创立的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
	if (g_pTexture1 != NULL)
	{
		g_pTexture1->Release();
	}
	if (g_pTexture2 != NULL)
	{
		g_pTexture2->Release();
	}
	if (g_pVertexBuf != NULL)
	{
		g_pVertexBuf->Release();
	}
	if (g_pd3dDevice != NULL)
	{
		g_pd3dDevice->Release();
	}
	if (g_pD3D != NULL)
	{
		g_pD3D->Release();
	}
}


//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render()
{
	//清除后台缓存区
	g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0);
	//设置变换矩阵
	SetupMatrices();

	//开始在后台缓冲区绘制图形
	if (SUCCEEDED(g_pd3dDevice->BeginScene()))
	{
		SetTexture();		//根据键盘按键确定纹理的寻址模式

		g_pd3dDevice->SetStreamSource(0, g_pVertexBuf, 0, sizeof(CUSTOMVERTEX));
		g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
		g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);		//绘制三角形带

		//结束在后台缓冲区绘制图形
	}
	g_pd3dDevice->EndScene();
	//将在后台缓冲区绘制的图形提交到前台缓冲区显示
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: 窗口消息处理函数
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		return 0;
	case WM_KEYDOWN:
		switch(wParam)
		{
		case 49:		//数字‘1’-‘4’键
			g_iTexAddressMode = 1;
			break;
		case 50:
			g_iTexAddressMode = 2;
			break;
		case 51:
			g_iTexAddressMode = 3;
			break;
		case 52:
			g_iTexAddressMode = 4;
			break;
		case VK_DOWN:
			g_fDistance -= 0.2f;		//摄像机距离图形的位置减小,图形缩小
			break;
		case VK_UP:
			g_fDistance += 0.2f;	//反之,增大	
			break;
		}
		return 0;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: 程序进口函数
//-----------------------------------------------------------------------------
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT)
{
	UNREFERENCED_PARAMETER(hInst);

	WNDCLASSEX wc = 
	{
		sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle(NULL), LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)),
		NULL, NULL, NULL, L"DirectTest", NULL
	};
	RegisterClassEx(&wc);

	HWND hWnd = CreateWindow(L"DirectTest", L"DirectTest 07 : TextureBase",
		WS_OVERLAPPEDWINDOW, 300, 150, 600, 500, NULL, NULL, wc.hInstance, NULL);
	if(SUCCEEDED(InitD3D(hWnd)))
	{
		if (SUCCEEDED(InitGriphics()))
		{
			ShowWindow(hWnd, SW_SHOWDEFAULT);
			UpdateWindow(hWnd);

			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"DirectTest", wc.hInstance);
	return 0;
}
    每日一道理
今天阳光很好,坐在窗前,看窗外如此晴朗的天感觉特别舒心,雨过天晴后的世界总给人一种明媚,仿佛阳光照耀在“心田”上空,让前些天被风雨践踏的花朵重新失掉爱的关怀,重现生命的活力!

    纹理和寻址

    纹理和寻址

    纹理和寻址

    纹理和寻址

    

文章结束给大家分享下程序员的一些笑话语录: 打赌
飞机上,一位工程师和一位程序员坐在一起。程序员问工程师是否乐意和他一起玩一种有趣的游戏。工程师想睡觉,于是他很有礼貌地拒绝了,转身要睡觉。程序员坚持要玩并解释说这是一个非常有趣的游戏:"我问你一个问题,如果你不知道答案,我付你5美元。然后你问我一个问题,如果我答不上来,我付你5美元。"然而,工程师又很有礼貌地拒绝了,又要去睡觉。  程序员这时有些着急了,他说:"好吧,如果你不知道答案,你付5美元;如果我不知道答案,我付50美元。"果然,这的确起了作用,工程师答应了。程序员就问:"从地球到月球有多远?"工程师一句话也没有说,给了程序员5美元。  现在轮到工程师了,他问程序员:"什么上山时有三条腿,下山却有四条腿?"程序员很吃惊地看着工程师,拿出他的便携式电脑,查找里面的资料,过了半个小时,他叫醒工程师并给了工程师50美元。工程师很礼貌地接过钱又要去睡觉。程序员有些恼怒,问:"那么答案是什么呢?"工程师什么也没有说,掏出钱包,拿出5美元给程序员,转身就去睡觉了。

--------------------------------- 原创文章 By
纹理和寻址
---------------------------------

原文地址:https://www.cnblogs.com/jiangu66/p/3105186.html