|
|
#include <d3d9.h>
#include <d3dx9.h>
LPDIRECT3D9 g_pD3D = NULL; // Direct3D对象指针
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // D3D设备指针
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // 顶点缓冲区
LPDIRECT3DTEXTURE9 g_pTexture = NULL; // 纹理对象1
LPDIRECT3DTEXTURE9 g_pTexture2 = NULL; // 纹理对象2
// 自定义的顶点类型:未经过坐标转换的顶点坐标,顶点漫反射颜色值,顶点纹理坐标
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ| D3DFVF_DIFFUSE| D3DFVF_TEX1)
struct CUSTOMVERTEX
{ FLOAT x, y, z; // 未经过坐标转换的顶点坐标
DWORD color; // 顶点漫反射颜色值
FLOAT u,v ; //顶点纹理坐标
};
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
//创建D3D对象.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// 获得当前显示模式
D3DDISPLAYMODE d3ddm;
if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;
// 填充结构以建立D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
// 创建D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitVB()
// Desc: 创建顶点缓冲区&纹理贴图。并且填充.
//-----------------------------------------------------------------------------
HRESULT InitVB()
{
if( FAILED( D3DXCreateTextureFromFileEx( g_pd3dDevice, "brick.jpg", 512,512,
5,0,D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT ,D3DX_DEFAULT,D3DX_DEFAULT,
0xFF000000,0,0,&g_pTexture ) ) )
{
/*
这个函数能够在创建纹理贴图的同时,自动生成多级纹理序列。
第1个参数:是有效的D3D设备指针
第2个参数:图形文件的路径和名称
第3个参数:纹理的宽度
第4个参数:纹理的高度
第5个参数:渐进纹理序列级数
第6个参数:纹理使用方式,一般为0
第7个参数:纹理图形格式
第8个参数:纹理存放的内存类型,一般为0
第9个参数:纹理过滤方式
第10个参数:自动生成的纹理序列过滤方式
第11个参数:设置透明色
第12个参数:图形文件信息存放地址,一般为0 累死我了,手都酸了。
第13个参数:调色板存储地址
第14个参数:创建的D3D文理指针存放地址
*/
return E_FAIL;
}
// 初始化顶点
CUSTOMVERTEX g_Vertices[] =
{
#define fdiv 80.f
{ -250.0f/fdiv, -250.0f/fdiv, 0.f, 0xffffffff, 0.f, 0},
{ 250.0f/fdiv , -250.0f/fdiv, 0.f, 0xffffffff, 1.0f, 0},
{ -250.0f/fdiv , 250.0f/fdiv, 0.f, 0xffffffff, 0, 1.0f},
{ 250.0f/fdiv, 250.0f/fdiv, 0.f, 0xffffffff, 1.0f, 1.0f}
};
// Create创建顶点缓冲区.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB,NULL ) ) )
{
return E_FAIL;
}
//现在我们填充顶点缓冲区,再次说明一下对顶点缓冲区进行操作必须通过Lock(),Unlock()来实现
VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
g_pVB->Unlock();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: 结束后系统系统资源收回
//-----------------------------------------------------------------------------
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 SetupMatrices()
{
// 模拟几何转换——》缩放
D3DXMATRIXA16 matWorld;
UINT iTime = timeGetTime() % 50000;//时间
FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 50000.0f;//角度
FLOAT fScale=(float)fabs(sin(fAngle));//缩放比例
D3DXMatrixScaling( &matWorld, fScale,fScale,fScale );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );//转换到世界坐标
//取景变换。请注意前面的帖子又详细解释
D3DXVECTOR3 vEyePt( 0.0f, .0f,-5 );
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: Render()
// Desc: 绘制
//-----------------------------------------------------------------------------
VOID Render()
{
// clear缓冲区颜色
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
SetupMatrices();
g_pd3dDevice->BeginScene();
g_pd3dDevice->SetTexture( 0, g_pTexture );//设置纹理状态,使用第一层纹理
//下面将纹理颜色和顶点漫反色值相乘输出到第一个纹理层,并禁用Alpha
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->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );//关闭剔除
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );//关闭光照
// 下面我不说了
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
g_pd3dDevice->EndScene();
g_pd3dDevice-> resent( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc:
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
Render();
ValidateRect( hWnd, NULL );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc:
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"Lid", NULL };
RegisterClassEx( &wc );
HWND hWnd = CreateWindow( "Lid", "Lid6 : 纹理",
WS_OVERLAPPEDWINDOW, 100, 100, 480, 480,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
if( SUCCEEDED( InitVB() ) )
{
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();
}
}
}
Cleanup();
UnregisterClass( "Lid", wc.hInstance );
return 0;
}
|
-
|