DirectX 3D_实践之DirectX3D纹理映射

                终于要回去了,谈不上兴奋,也谈不上高兴。总体感觉是正向的。目前,我还想继续在这里呆下去,因为一直跳来跳去,永远也积累不了人脉和关系,对于现在的我来说,往往这是最最重要的,需要知道别人的长处,谁会什么,谁有什么性格,谁适合做什么,回公司,可以和同事们多多接触,积累下关系和人脉。我不应该,羡慕别人多那么点工资,这个往往都是眼前利益,虽然自己如果出去,工资,是会有很大的提高,但这样,也必将承担那么大的压力,我到不是怕压力,只是想目前在家旁边呆着,毕竟自己生长在这个地方,机会也会比外面多些。打工不是长久之计,所以,我应该才现在开始,时刻准备着。

 

             今天我们看一下Direct3D中的纹理,书上有三个例子,这里,我只用了一个,后续再说:

还是先看一下,DirectX3D.h

#ifndef __DirectX3DH__
#define __DirectX3DH__

#include <d3dx9.h>
#include <string>

namespace d3d
{
	bool InitD3D(
		HINSTANCE hInstance,       // [in] Application instance.
		int width, int height,     // [in] Backbuffer dimensions.
		bool windowed,             // [in] Windowed (true)or full screen (false).
		D3DDEVTYPE deviceType,     // [in] HAL or REF
		IDirect3DDevice9** device);// [out]The created device.
	
	int EnterMsgLoop( 
		bool (*ptr_display)(float timeDelta));
	
	LRESULT CALLBACK WndProc(
		HWND hwnd,
		UINT msg, 
		WPARAM wParam,
		LPARAM lParam);
	
	template<class T> void Release(T t)
	{
		if( t )
		{
			t->Release();
			t = 0;
		}
	}
	
	template<class T> void Delete(T t)
	{
		if( t )
		{
			delete t;
			t = 0;
		}
	}
	
	const D3DXCOLOR      WHITE( D3DCOLOR_XRGB(255, 255, 255) );
	const D3DXCOLOR      BLACK( D3DCOLOR_XRGB(  0,   0,   0) );
	const D3DXCOLOR        RED( D3DCOLOR_XRGB(255,   0,   0) );
	const D3DXCOLOR      GREEN( D3DCOLOR_XRGB(  0, 255,   0) );
	const D3DXCOLOR       BLUE( D3DCOLOR_XRGB(  0,   0, 255) );
	const D3DXCOLOR     YELLOW( D3DCOLOR_XRGB(255, 255,   0) );
	const D3DXCOLOR       CYAN( D3DCOLOR_XRGB(  0, 255, 255) );
	const D3DXCOLOR    MAGENTA( D3DCOLOR_XRGB(255,   0, 255) );
	
	//
	// Lights
	//
/*	
	D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
	D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
	D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);
	
	//
	// Materials
	//
	
	D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);
	
	const D3DMATERIAL9 WHITE_MTRL  = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
	const D3DMATERIAL9 RED_MTRL    = InitMtrl(RED, RED, RED, BLACK, 2.0f);
	const D3DMATERIAL9 GREEN_MTRL  = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
	const D3DMATERIAL9 BLUE_MTRL   = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
	const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);
*/
}

#endif 


在看一下,DirectX3D.cpp

#include "DirectX3D.h"

bool d3d::InitD3D(
	HINSTANCE hInstance,
	int width, int height,
	bool windowed,
	D3DDEVTYPE deviceType,
	IDirect3DDevice9** device)
{
	//
	// Create the main application window.
	//

	WNDCLASS wc;

	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = (WNDPROC)d3d::WndProc; 
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
	wc.hCursor       = LoadCursor(0, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = 0;
	wc.lpszClassName = "Direct3D9App";

	if( !RegisterClass(&wc) ) 
	{
		::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
		return false;
	}
		
	HWND hwnd = 0;
	hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", 
		WS_EX_TOPMOST,
		0, 0, width, height,
		0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); 

	if( !hwnd )
	{
		::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
		return false;
	}

	::ShowWindow(hwnd, SW_SHOW);
	::UpdateWindow(hwnd);

	//
	// Init D3D: 
	//

    //第一步
    //要初始化IDirect3D 首先必须获取IDirect3D9的指针,使用一个专门的Direct3D函数就可以很容易做到
     IDirect3D9 * _d3d9;
  
  //这个对象的主要有两个用途:设备枚举以及创建IDirect3DDevice9类型的对象。设备枚举是指获取系统中可用的的每块图形卡的
  //性能,显示模型,格式以及其他信息。这个函数调用失败会返回一个NULL指针。
  if(NULL == (_d3d9 = Direct3DCreate9(D3D_SDK_VERSION))){


    return FALSE;

  }

  //第二步
  //创建一个代表主显卡的IDirect3DDevice9类型对象时,必须指定使用该对象进行顶点运算的类型。如果可以,我们希望使用硬件顶点运算
  //但是由于并非所有的显卡都支持硬件顶点运算,我们必须首先检查图形卡是否支持该类型的运算。

  //要进行检查,必须先根据主显卡的性能参数初始化一个IDirect3DDevice9类型的对象。我们使用如下方法来完成初始化:
     /*
  HRESULT IDirect3D9:GetDeviceCaps(
      UINT Adapter,
      D3DDEVTYPE DeviceType,
      D3DCAPS9 * pCaps;
   
  )

        Adapter : 指定物理显卡的序号。
  DeviceType:指定设备类(例如硬件设备(D3DDEVTYPE_HAL)或软件设备(D3DDEVTYPE_REF));
  pCaps 返回已初始化的设备性能结构实例。
        */
         D3DCAPS9 caps; 
         int vp = 0; //代表顶点如何操作

        _d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);

          if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){

                        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
           }
          else
          {
                        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
          }

          //第三步是填充D3DPRESENT_PARAMETER结构
          //该结构用于指定所要创建的IDirect3DDevice9类型对象的一些特性,该结构定义如下:
          /*
          typedef struct _D3DPRESENT_PARAMETERS_{
                        UINT BackBufferWidth;
                        UINT BackBufferHeight;
                        UINT BackBufferFormat;
                        UINT BackBufferCount;
                        D3DMULTISAMPLE_TYPE MultiSampleType;
                        DWORD MultiSampleQuality;
                        D3DSWAPEFFECT SwapEffect;
                        HWND  hDeviceWindow;
                        BOOL  Windowed;
                        BOOL  EnableAutoDepthStencil;
                        D3DFORMAT AutoDepthStencilFormat;
                        DWORD  Flags;
                        UINT   FullScreen_RefreshRateInHz;
                        UINT   PresentationInterval;
          }; 
         */
        
        /* 
         BackBufferWidth: 后台缓存中表面的宽度,单位为像素。
        BackBufferHeight:后台缓存中表面的高度,单位为像素。
        BackBufferFormat:后台缓存的像素格式(如32位像素格式:D3DFMT_A8R8G8B8);
        BackBufferCount: 所需使用的后台缓存的个数,通常指定为1,表明我们仅需要一个后台缓存。
        MultiSampleType: 后台缓存所使用的多重采样类型。
        MultiSampleQuality:多重采样的质量水平。
        SwapEffect:D3DSWAPEFFECT 枚举类型的一个成员。该枚举类型指定了交换链中的缓存的页面置换方式。指定D3DSWAPEFFECT_DISCARD时效率最高。
        hDeviceWindow:与设备相关的窗口句柄。指定了所要进行绘制的应用程序窗口。
        Windowed:为true时表示窗口模式,false时为全屏模式
        EnableAutoDepthStencil:设为true,则Direct3D自动创建并维护深度缓存或模板缓存。
        AutoDepthStencilFormat:深度缓存或模板缓存的像素格式(例如,用24位表示深度并将8位保留供模板缓存使用,D3DFMT_D24S8).
        Flags:一些附加的特性。可以指定为0,表示无标记,或D3DPRESENTFLAG集合中的一个成员,其中两个成员较常用。
                 D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 指定为可锁定的后台缓存。注意,使用一个可锁定的后台缓存会降低性能。
                 D3DPRESENTFLAG_DISCARD_DEPTHBUFFER 指定当下一个后台缓存提交时,哪个深度或模块缓存将被丢弃。丢弃的意思是深度或模板缓存存储区
                                                    中的内容别丢弃或无效。这样可以提升性能。
        FullScreen_RefreshRateInHz: 刷新频率,如果想使用默认的刷新频率,则可将该参数指定为D3DPRESENT_RATE_DEFAULT;
        PresentationInterval:D3DPRESENT集合的一个成员,其中有两个比较常用。
                      D3DPRESENT_INTERVAL_IMMEDIATE 立即提交。
                      D3DPRESENT_INTERVAL_DEFAULT 由Direct3D来选择提交频率,通常该值等于刷新频率。
       */ 

                  D3DPRESENT_PARAMETERS d3dpp;  
                  ZeroMemory(&d3dpp, sizeof(d3dpp));  
                 d3dpp.BackBufferWidth            = 800;  
                 d3dpp.BackBufferHeight           = 600;  
                 d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;  
                 d3dpp.BackBufferCount            = 1;  
                 d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;  
                 d3dpp.MultiSampleQuality         = 0;  
                 d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;   
                 d3dpp.hDeviceWindow              = hwnd;  
                 d3dpp.Windowed                   = true;  
                 d3dpp.EnableAutoDepthStencil     = true;   
                 d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;  
                 d3dpp.Flags                      = 0;  
                 d3dpp.FullScreen_RefreshRateInHz = 0;  
                 d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE; 

              //第四步 创建IDirectDevice9类型的对象
               /*  
                       HRESULT IDirect3D9::CreateDevice(
                               UINT Adapter,
                               D3DDEVTYPE DeviceType,
                               HWND hFocusWindow,
                               DWORD BehaviorFlags,
                               D3DPRESENT_PARAMETERS *pPresentationParameters,
                               IDirect3DDevice9 ** ppReturnedDeviceInterface
   
   
                       );

       Adapter:指定我们希望用已创建的IDirect3DDevice9对象代表哪块物理显卡。
       DeviceType:指定需要使用的设备类型()如,硬件设备用D3DDEVTYPE_HAL,或D3DDEVTYPE_REF代表软件设备。
       hFocusWindow:与设备相关的窗口句柄。通常情况下是指设备所要进行绘制的目标窗口。
       为了达到预期的目的,该句柄与D3DPRESENT_PARAMETER结构的数据成员hDeviceWindow应为同一个句柄。
       BehaviorFlags:该参数可为D3DCREATE_HARDWARE_VERTEXPROCESSING或D3DCREATE_SOFTWARE_VERTEXPROCESSING.
       pPresentationParameters:一个已经完成初始化的D3DPRESENT_PARAMETERS类型的实例,该实例定义了设备的一些特性。
       ppReturnedDeviceInterface:返回所创建的设备。
*/
  if(FAILED(_d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,   
   hwnd, vp, &d3dpp, device)))  
           return FALSE;  

      _d3d9->Release();

      return TRUE;


}

int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
	MSG msg;
	::ZeroMemory(&msg, sizeof(MSG));

	static float lastTime = (float)timeGetTime(); 

	while(msg.message != WM_QUIT)
	{
		if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
		else
        {	
			float currTime  = (float)timeGetTime();
			float timeDelta = (currTime - lastTime)*0.001f;

			ptr_display(timeDelta);

			lastTime = currTime;
        }
    }
    return msg.wParam;
}


在看一下wmain.cpp

#include "DirectX3D.h"
#include <fstream>
#include <vector>
//
// Globals
//

IDirect3DDevice9* Device = 0; 

IDirect3DTexture9 * Tex = 0;

IDirect3DVertexBuffer9 * Quad = 0;//顶点缓存的指针


//初始化两个全局常量,以定义屏幕的分辨率。r
const int Width = 800;
const int Height = 600;

//这里,我们需要在灵活顶点格式中增加顶点的纹理坐标。

struct Vertex
{
	Vertex(){}
	
	Vertex(float x, float y, float z, float nx, float ny, float nz,float u,float v)
	{
		_x  = x;  _y  = y;	_z  = z;
		_nx = nx; _ny = ny; _nz = nz;
		_u = u;_v = v;
	}
	float  _x,  _y,  _z;
	float _nx, _ny, _nz;
	float _u,_v;
	
	static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
//
// Framework Functions
//
//面我们在Setup函数里面创建顶点缓存和索引缓存,
//然后对缓存进行锁定,这里我们没有用到索引缓存
bool Setup()
{
	// Nothing to setup in this sample.
    //启用光照,默认状态下,光照就是启用的。
	Device->SetRenderState(D3DRS_LIGHTING,true);

    //创建顶点缓存
	Device->CreateVertexBuffer(
		   6*sizeof(Vertex),
		   D3DUSAGE_WRITEONLY,
		   Vertex::FVF,
		   D3DPOOL_MANAGED,
		   &Quad,
		   0);
	//回忆一下这个函数的参数
	/*
	第一个参数是缓存空间的大小,这里分配3个顶点结构的字节数。
	第二个参数是使用缓存的属性,这里用的只写属性,后面如果读就会有问题。
	第三个参数,顶点的灵活顶点格式。
	第四个参数,容纳缓存的内存池。
	*/
		

    
	Vertex * v;//定义一个顶点结构的指针,用来装从Triangle得到的分配的顶点空间。

	Quad->Lock(0,0,(void**)&v,0);

	//回忆一下lock的参数,第一个是锁定的VB的偏移,第二个是锁定的字节数,第四个是锁定的方式。


	//下面给顶点赋值。2个三角形
    //前面

	v[0] = Vertex(-1.0f, -1.0f, 1.25f,0.0f,0.0f,-1.0f,0.0f,3.0f);
	v[1] = Vertex(-1.0f,1.0f,1.25f,0.0f,0.0f,-1.0f,0.0f,0.0f);
	v[2] = Vertex(1.0f,1.0f,1.25f,0.0f,0.0f,-1.0f,3.0f,0.0f);
	
	

	v[3] = Vertex(-1.0f,-1.0f,1.25f,0.0f,0.0f,-1.0f,0.0f,3.0f);
	v[4] = Vertex(1.0f,1.0f,1.25f,0.0f,0.0f,-1.0f,3.0f,0.0f);
	v[5] = Vertex(1.0f,-1.0f,1.25f,0.0f,0.0f,-1.0f,3.0f,3.0f);
	

	
	Quad->Unlock();
     
    
    //创建纹理
	/*
	这个函数的参数比较简单
	*/
    D3DXCreateTextureFromFile(
		Device,
		"dx5_logo.bmp",
		&Tex
		);


	Device->SetTexture(0,Tex);

    /*
	设置纹理的采样过滤器状态
	*/

	//线性纹理过滤,将线性纹理过滤设置为放大过滤器和缩小过滤器。效果依据硬件水平。
	//Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
	//Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);

	//最近采样点纹理过滤设置为放大过滤器和缩小过滤器。效果最差
	//Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT);
	//Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT);

	//各向异性纹理过滤设置为放大过滤器和缩小过滤器。效果最好
	Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
	Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);

    //多级渐近纹理过滤器。
	//Device->SetSampleState(0,D3DSAMP_MIPFILTER,Filter);
	//Filter可以取如下值:
	/*
	D3DTEXF_NONE 禁用多级渐进纹理过滤器
	D3DTEXF_POINT 通过使用该过滤器,DirectX3D将尺寸与屏幕三角形最接近的那一级纹理,一旦选择了某一级纹理
	Direct3D就会用指定的放大过滤器和放小过滤器对该级纹理进行过滤
	D3DTEXF_LINEAR 通过使用该过滤器,Direct3D将取与屏幕三角形尺寸最接近的两个纹理级,用指定的放大器和缩小过滤器
	对每级纹理进行过滤,然后再将两级纹理进行线性组合,从而形成最终的颜色值。
	
	*/
	Device->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR);

	//禁用光照
	Device->SetRenderState(D3DRS_LIGHTING,false);
	
	//
	// Set the projection matrix.
	//
	
	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(
		&proj,
		D3DX_PI * 0.5f, // 90 - degree
		(float)Width / (float)Height,
		1.0f,
		1000.0f);

	Device->SetTransform(D3DTS_PROJECTION, &proj);



	return true;
}
//将之前分配的内存进行清理,也就是顶点缓存和索引缓存
void Cleanup()
{

	d3d::Release<IDirect3DVertexBuffer9*>(Quad);

	// Nothing to cleanup in this sample.
}

/*
这里的Display在两个不同的位置以两种不同的着色模式分别绘制了Triangle。每个三角形的位置由世界变换矩阵World来控制

*/

bool Display(float timeDelta)
{
	if( Device ) // Only use Device methods if we have a valid device.
	{
        //设置寻址模式
		/*
		前面,我们说过,纹理坐标必须限定在区间[0,1]内,这是有问题的,因为有时坐标可能超出该范围。
		Direct3D定义了4种用来处理纹理坐标值超出[0,1]区间的纹理映射模式,它们分别是
		*/
		// 重复寻址模式
		if( ::GetAsyncKeyState('W') & 0x8000f )
		{
			Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
			Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
		}
		
		// 边界颜色寻址模式
		if( ::GetAsyncKeyState('B') & 0x8000f )
		{
			Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
			Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
			Device->SetSamplerState(0,  D3DSAMP_BORDERCOLOR, 0x000000ff);
		}
		
		// 箝位寻址模式
		if( ::GetAsyncKeyState('C') & 0x8000f )
		{
			Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
			Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
		}
		
		// 镜像寻址模式
		if( ::GetAsyncKeyState('M') & 0x8000f )
		{
			Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
			Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
		}	

	
		Device -> Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0xffffffff,1.0f,0);

		//所有的绘制方法都必须在BeginScene和EndScene中进行调用

		Device->BeginScene();

	

        //SetStreamSource函数,第一个参数是,资源号,比如有几个顶点缓存,第二个参数,顶点缓存的指针接口,
		//第三个参数,是顶点缓存数据结构中的偏移字节。第四个是,顶点缓存的大小。
		Device->SetStreamSource(0,Quad,0,sizeof(Vertex));

			Device->SetFVF(Vertex::FVF);

        // 第一种模式 DrawPrimitive这个函数,专门用于绘制没有索引信息的图元。
		/* 第一个参数是,图元的类型,
		typedef enum D3DPRIMITIVETYPE {
		D3DPT_POINTLIST       = 1,
		D3DPT_LINELIST        = 2,
		D3DPT_LINESTRIP       = 3,
		D3DPT_TRIANGLELIST    = 4,
		D3DPT_TRIANGLESTRIP   = 5,
		D3DPT_TRIANGLEFAN     = 6,
		D3DPT_FORCE_DWORD     = 0x7fffffff 
		} D3DPRIMITIVETYPE, *LPD3DPRIMITIVETYPE;

		 第二个参数,顶点数据流中标识顶点数据读取起点的元素的索引。该参数赋予我们一定的自由度
		 使得,我们可以只对顶点缓存中的某一部分进行绘制。
		 第三个参数,所要绘制的图元数量。

         关于D3DRS_SHADEMODE,一般规定了我们如何利用顶点的颜色来计算构成图元的像素的颜色,目前一般我们
		 使用两种着色模式,分别是平面着色D3DSHADE_FLAT ,另一种是,D3DSHADE_GOURAUD。

         D3DSHADE_FLAT 着色,每个图元的每个像素都被一直地赋予该图元的第一个顶点所指定的颜色。屏幕颜色
		 容易呈现出块状,这是因为个颜色之间没有平滑的过度。另一种更好的着色模式是D3DSHADE_GOURAUD,也
		 称平滑着色,在这种模式下,图元中的各像素的颜色值由各顶点的颜色经线性插值得到。
		
		*/

		
		Device->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);


		Device->EndScene();


		
		// Swap the back and front buffers.
		Device->Present(0, 0, 0, 0);
	}
			return true;
}	

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch( msg )
	{
	case WM_DESTROY:
		::PostQuitMessage(0);
		break;
		
	case WM_KEYDOWN:
		if( wParam == VK_ESCAPE )
			::DestroyWindow(hwnd);
		break;
	}
	return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE prevInstance, 
				   PSTR cmdLine,
				   int showCmd)
{
	if(!d3d::InitD3D(hinstance,
		640, 480, true, D3DDEVTYPE_HAL, &Device))
	{
		::MessageBox(0, "InitD3D() - FAILED", 0, 0);
		return 0;
	}
	
	if(!Setup())
	{
		::MessageBox(0, "Setup() - FAILED", 0, 0);
		return 0;
	}
	
	d3d::EnterMsgLoop( Display );
	
	Cleanup();
	
	Device->Release();
	
	return 0;
}

看一下程序运行的截图:

 

每日总结:

1,我们为场景添加纹理映射的步骤。

      1.1,构造组成物体的顶点,并为其指定纹理坐标。

      1.2,用函数D3DXCreateTextureFromFile为IDirect3DTexture9接口加载一种纹理。

      1.3,设置缩小过滤器,放大过滤器和多级渐近纹理过滤器。

      1.4,绘制物体前,用函数IDirect3DDevice9::SetTexture来设定与该物体关联的纹理。

2,  纹理坐标用于定义将被映射到3D三角形的纹理子区域。

3,我们可借助D3DXCreateTextureFromFile函数由存储在磁盘上的图像文件创建纹理。

4,我们可用缩小过滤器,放大过滤器和多级渐近纹理过滤器的采样状态对纹理实施过滤。

5,纹理寻址模式用于定义当纹理坐标值超出[0,1]区间时,Direct3D应怎样对纹理进行映射。例如,纹理应采用重复寻址模式,镜像寻址模式还是箝位寻址模式。

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值