Teodomiro
13-09-2007, 13:41
Salve a tutti!
Sto iniziando a utilizzare le DirectX ed ho già incontrato un ostacolo che non riesco a superare :mc:
Finora, nonostante l'uso di SetTransform(...) per impostare world matrix, view matrix e e portview, le DrawPrimitive continuano a disegnare interpretando i vertici come coordinate schermo.
C'è qualche istruzione che "attiva" le trasformazioni di coordinate? Sono proprio incasinato . . . :confused:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
LPDIRECT3D9 pD3D; //oggetto
LPDIRECT3DDEVICE9 pd3dDevice; //device
IDirect3DVertexBuffer9* vBuffer;
IDirect3DSurface9* pD3DSurface;
const int DSP_LARG = 1024; //
const int DSP_ALT = 768;
LARGE_INTEGER timerStart, timerEnd, timerFreq;
float anim_rate;
int nFrame = 0;
const char g_szClassName[] = "LaMiaClasseWindow";
void Render();
void InitD3D(HWND);
void CleanUp();
struct CUSTOMVERTEX
{
FLOAT x,y,z, rhw;
DWORD color;
};
CUSTOMVERTEX g_vertici[3] =
{{0.0f, 0.0f, 1.0f, 1.0f, 0x00FF0000},
{10.0f, 0.0f, 1.0f, 1.0f, 0x00FFFF00},
{0.0f, 10.0f, 1.0f, 1.0f, 0x00FF00FF}};
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hDC; // dichiaro l'handle al drive context
static int contatore = 1;
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
CleanUp();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
{
PostQuitMessage(0);
return 0;
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //IDC_CROSS);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Prova Rotazioni",
WS_POPUP |WS_EX_TOPMOST| WS_VISIBLE, //| WS_DLGFRAME,
0,0,1024,768,
NULL, NULL, hInstance, NULL);
InitD3D(hwnd); //inizializzo DirectX
//*****************************************************************************************
//*****************************************************************************************
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
ShowCursor(FALSE);
// Step 3: The Message Loop
QueryPerformanceFrequency(&timerFreq);//ricavo la frequenza
while( TRUE )
{
if( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE ) )
{
// Check for a quit message
if( Msg.message == WM_QUIT )
break;
TranslateMessage( &Msg );
DispatchMessage( &Msg );
}
else
{
QueryPerformanceCounter(&timerStart);
Render();
QueryPerformanceCounter(&timerEnd);
anim_rate = (float)(timerEnd.QuadPart - timerStart.QuadPart)/timerFreq.QuadPart;
}
}
}
void InitD3D(HWND wnd)
{
pD3D = Direct3DCreate9 (D3D_SDK_VERSION); //creo l'object
if(NULL == pD3D)
{
MessageBox(NULL, "Errore nella creazione dell\'object",NULL,MB_OK);
return;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = false;// Full Screen, quindi cambia anche la risoluzione del monitor
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount =1;
d3dpp.BackBufferHeight = DSP_ALT;
d3dpp.BackBufferWidth = DSP_LARG;
d3dpp.hDeviceWindow = wnd;
//creo il device:
HRESULT hret = 0;
hret = pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
wnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &pd3dDevice);
if(FAILED(hret))
{
char lpMess[255];
switch (hret)
{
case D3DERR_DEVICELOST:
strcpy(lpMess,"Errore device_lost");
break;
case D3DERR_INVALIDCALL:
strcpy(lpMess,"Errore D3DERR_INVALIDCALL");
break;
case D3DERR_NOTAVAILABLE:
strcpy(lpMess,"Errore D3DERR_NOTAVAILABLE");
break;
case D3DERR_OUTOFVIDEOMEMORY:
strcpy(lpMess,"Errore D3DERR_OUTOFVIDEOMEMORY");
break;
}
MessageBox(NULL, lpMess ,"Errore",MB_OK);
return;
}
hret = pd3dDevice->CreateVertexBuffer(sizeof(g_vertici), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
D3DPOOL_DEFAULT, &vBuffer, NULL);
if(FAILED(hret))
{
return ;
}
}
void CleanUp()
{
if(pD3D != NULL)
pD3D->Release();
if(pd3dDevice != NULL)
pd3dDevice->Release();
}
void Render()
{
IDirect3DSurface9* backBuffer;
DWORD hret;
if (NULL == pd3dDevice)
{
return;
}
static float tempo = 0.0f;
pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backBuffer);
// pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
/////////////////////////////////////////////////////////////////////////////////////////////
void * pVertici; //buffer di lavoro che conterrà i vertici copiati
hret = vBuffer->Lock(0, sizeof(g_vertici), (void **) &pVertici, 0);
memcpy(pVertici, g_vertici, sizeof(g_vertici));
vBuffer->Unlock();
//-----------------------------------------------####################
/// rotazioni
D3DXMATRIX finalMat, dummyMat, matRotazione, matProj, matTraslazione;
D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX v;
D3DXMatrixIdentity(&matRotazione); //inizializzo la matrice identità
D3DXMatrixIdentity(&matTraslazione); //inizializzo la matrice identità
D3DXMatrixIdentity(&finalMat);
//alimento la matrice di rotazione:
D3DXMatrixRotationZ(&matRotazione, D3DX_PI * 0.25f);
D3DXMatrixTranslation(&matTraslazione, 400.0f, 100.0f, 0.0f);
D3DXMatrixMultiply(&finalMat, &finalMat, &matTraslazione); //apply translation
//applico la rotazione moltiplicando:
D3DXMatrixMultiply(&finalMat, &finalMat, &matRotazione);
pd3dDevice->SetTransform(D3DTS_WORLD, &finalMat);
D3DXMatrixLookAtLH(&v, &position, &target, &up);
pd3dDevice->SetTransform(D3DTS_VIEW, &v);
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI * 1.5f, (float) 1024 / (float) 768, 1.0f, 100.0f);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
hret = pd3dDevice->BeginScene();
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in BeginScene()","Errore",MB_OK);
return;
}
hret = pd3dDevice->SetStreamSource(0, vBuffer, 0, sizeof(CUSTOMVERTEX));//dichiaro quale buffer usare per i vertici
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in SetStreamSource","Errore",MB_OK);
return;
}
hret = pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in SetFVF","Errore",MB_OK);
return;
}
D3DVIEWPORT9 vp = { 0, 0, 1024, 768, 0.0f, 1.0f };
pd3dDevice->SetViewport(&vp);
hret = pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST,0,1);
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in DrawIndexedPrimitive","Errore",MB_OK);
return;
}
pd3dDevice->EndScene();
nFrame++;
pd3dDevice->Present(NULL, NULL, NULL, NULL);
tempo += anim_rate;
}
;
Sto iniziando a utilizzare le DirectX ed ho già incontrato un ostacolo che non riesco a superare :mc:
Finora, nonostante l'uso di SetTransform(...) per impostare world matrix, view matrix e e portview, le DrawPrimitive continuano a disegnare interpretando i vertici come coordinate schermo.
C'è qualche istruzione che "attiva" le trasformazioni di coordinate? Sono proprio incasinato . . . :confused:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
LPDIRECT3D9 pD3D; //oggetto
LPDIRECT3DDEVICE9 pd3dDevice; //device
IDirect3DVertexBuffer9* vBuffer;
IDirect3DSurface9* pD3DSurface;
const int DSP_LARG = 1024; //
const int DSP_ALT = 768;
LARGE_INTEGER timerStart, timerEnd, timerFreq;
float anim_rate;
int nFrame = 0;
const char g_szClassName[] = "LaMiaClasseWindow";
void Render();
void InitD3D(HWND);
void CleanUp();
struct CUSTOMVERTEX
{
FLOAT x,y,z, rhw;
DWORD color;
};
CUSTOMVERTEX g_vertici[3] =
{{0.0f, 0.0f, 1.0f, 1.0f, 0x00FF0000},
{10.0f, 0.0f, 1.0f, 1.0f, 0x00FFFF00},
{0.0f, 10.0f, 1.0f, 1.0f, 0x00FF00FF}};
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hDC; // dichiaro l'handle al drive context
static int contatore = 1;
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
CleanUp();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
{
PostQuitMessage(0);
return 0;
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //IDC_CROSS);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Prova Rotazioni",
WS_POPUP |WS_EX_TOPMOST| WS_VISIBLE, //| WS_DLGFRAME,
0,0,1024,768,
NULL, NULL, hInstance, NULL);
InitD3D(hwnd); //inizializzo DirectX
//*****************************************************************************************
//*****************************************************************************************
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
ShowCursor(FALSE);
// Step 3: The Message Loop
QueryPerformanceFrequency(&timerFreq);//ricavo la frequenza
while( TRUE )
{
if( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE ) )
{
// Check for a quit message
if( Msg.message == WM_QUIT )
break;
TranslateMessage( &Msg );
DispatchMessage( &Msg );
}
else
{
QueryPerformanceCounter(&timerStart);
Render();
QueryPerformanceCounter(&timerEnd);
anim_rate = (float)(timerEnd.QuadPart - timerStart.QuadPart)/timerFreq.QuadPart;
}
}
}
void InitD3D(HWND wnd)
{
pD3D = Direct3DCreate9 (D3D_SDK_VERSION); //creo l'object
if(NULL == pD3D)
{
MessageBox(NULL, "Errore nella creazione dell\'object",NULL,MB_OK);
return;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = false;// Full Screen, quindi cambia anche la risoluzione del monitor
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount =1;
d3dpp.BackBufferHeight = DSP_ALT;
d3dpp.BackBufferWidth = DSP_LARG;
d3dpp.hDeviceWindow = wnd;
//creo il device:
HRESULT hret = 0;
hret = pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
wnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &pd3dDevice);
if(FAILED(hret))
{
char lpMess[255];
switch (hret)
{
case D3DERR_DEVICELOST:
strcpy(lpMess,"Errore device_lost");
break;
case D3DERR_INVALIDCALL:
strcpy(lpMess,"Errore D3DERR_INVALIDCALL");
break;
case D3DERR_NOTAVAILABLE:
strcpy(lpMess,"Errore D3DERR_NOTAVAILABLE");
break;
case D3DERR_OUTOFVIDEOMEMORY:
strcpy(lpMess,"Errore D3DERR_OUTOFVIDEOMEMORY");
break;
}
MessageBox(NULL, lpMess ,"Errore",MB_OK);
return;
}
hret = pd3dDevice->CreateVertexBuffer(sizeof(g_vertici), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
D3DPOOL_DEFAULT, &vBuffer, NULL);
if(FAILED(hret))
{
return ;
}
}
void CleanUp()
{
if(pD3D != NULL)
pD3D->Release();
if(pd3dDevice != NULL)
pd3dDevice->Release();
}
void Render()
{
IDirect3DSurface9* backBuffer;
DWORD hret;
if (NULL == pd3dDevice)
{
return;
}
static float tempo = 0.0f;
pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backBuffer);
// pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
/////////////////////////////////////////////////////////////////////////////////////////////
void * pVertici; //buffer di lavoro che conterrà i vertici copiati
hret = vBuffer->Lock(0, sizeof(g_vertici), (void **) &pVertici, 0);
memcpy(pVertici, g_vertici, sizeof(g_vertici));
vBuffer->Unlock();
//-----------------------------------------------####################
/// rotazioni
D3DXMATRIX finalMat, dummyMat, matRotazione, matProj, matTraslazione;
D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX v;
D3DXMatrixIdentity(&matRotazione); //inizializzo la matrice identità
D3DXMatrixIdentity(&matTraslazione); //inizializzo la matrice identità
D3DXMatrixIdentity(&finalMat);
//alimento la matrice di rotazione:
D3DXMatrixRotationZ(&matRotazione, D3DX_PI * 0.25f);
D3DXMatrixTranslation(&matTraslazione, 400.0f, 100.0f, 0.0f);
D3DXMatrixMultiply(&finalMat, &finalMat, &matTraslazione); //apply translation
//applico la rotazione moltiplicando:
D3DXMatrixMultiply(&finalMat, &finalMat, &matRotazione);
pd3dDevice->SetTransform(D3DTS_WORLD, &finalMat);
D3DXMatrixLookAtLH(&v, &position, &target, &up);
pd3dDevice->SetTransform(D3DTS_VIEW, &v);
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI * 1.5f, (float) 1024 / (float) 768, 1.0f, 100.0f);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
hret = pd3dDevice->BeginScene();
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in BeginScene()","Errore",MB_OK);
return;
}
hret = pd3dDevice->SetStreamSource(0, vBuffer, 0, sizeof(CUSTOMVERTEX));//dichiaro quale buffer usare per i vertici
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in SetStreamSource","Errore",MB_OK);
return;
}
hret = pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in SetFVF","Errore",MB_OK);
return;
}
D3DVIEWPORT9 vp = { 0, 0, 1024, 768, 0.0f, 1.0f };
pd3dDevice->SetViewport(&vp);
hret = pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST,0,1);
if(FAILED(hret))
{
MessageBox(NULL, "ERRORE in DrawIndexedPrimitive","Errore",MB_OK);
return;
}
pd3dDevice->EndScene();
nFrame++;
pd3dDevice->Present(NULL, NULL, NULL, NULL);
tempo += anim_rate;
}
;