Jag har skrivit ett program som använder DirectX 9. Till att börja med måste du först instansiera D3D9 och D3DDevice9 vilket också kräver en handle till fönstret: Kan du ge ett exempel på hur CXSurface::CreateSurface skulle se ut om man använde D3DXCreateTextureFromFile gör hela surface grejen onödig eftersom funktionen automatiskt kommer att skapa en surface till texturen. Jag vet inte riktigt hur det är tänkt att fungera heller men för att skapa en texture kan du göra nåt i stil med nedanstående. Tack för hjälpen!Fel vid programkörning
När jag kör programet visas ett felmeddelande:
Unhandled exception at 0x00401007 in UILib.exe: 0xC0000005: Access violation reading location 0x00000000.
Här är källkoden till programet:
main.cpp
<code>
//*****Inkluderingsfiler*****//
#include <d3d9.h>
#include <d3dx9.h>
#include "dxwrappers.h"
//*****Globala variabler*****//
IDirect3D9* g_pD3D = NULL;
IDirect3DDevice9* g_pD3DDevice = NULL;
CXSurface* g_Surf;
//*****Funktioner*****//
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void Render();
void InitD3D();
void CleanUp();
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
(LPCSTR)"D3D", NULL};
RegisterClassEx(&wc);
HWND hWnd = CreateWindow((LPCSTR)"D3D", (LPCSTR)"D3D", WS_OVERLAPPEDWINDOW,
100, 100, 300, 300,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
InitD3D();
MSG msg;
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
UnregisterClass((LPCSTR)"D3D", wc.hInstance);
}
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
CleanUp();
return 0;
case WM_PAINT:
Render();
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void Render()
{
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if (SUCCEEDED(g_pD3DDevice->BeginScene()))
{
//Rendera här!
g_Surf->Render();
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
}
void InitD3D()
{
g_Surf = new CXSurface(g_pD3DDevice);
g_Surf->LoadFromFile("bild.bmp");
}
void CleanUp()
{
delete g_Surf;
}
</code>
dxwrappers.h
<code>
class CXSurface
{
private:
LPDIRECT3DSURFACE9 m_Surface;
LPDIRECT3DDEVICE9 m_pDevice;
protected:
public:
CXSurface();
CXSurface(LPDIRECT3DDEVICE9 pDevice);
CXSurface(LPDIRECT3DDEVICE9 pDevice, const char* Path);
~CXSurface();
LPDIRECT3DSURFACE9 GetSurface() {return m_Surface;}
void SetSurface(LPDIRECT3DSURFACE9 Surf) {m_Surface = Surf;}
LPDIRECT3DDEVICE9 GetDevice() {return m_pDevice;}
void SetDevice(LPDIRECT3DDEVICE9 pDevice) {m_pDevice = pDevice;}
HRESULT CreateSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool);
HRESULT LoadFromFile(const char* Path);
HRESULT MakeBackBuffer(void);
HRESULT PasteFromSurface(CXSurface* Source, RECT* pSourceRect, int X, int Y);
void Render();
};
CXSurface::CXSurface()
{
this->SetDevice(NULL);
this->SetSurface(NULL);
}
CXSurface::CXSurface(LPDIRECT3DDEVICE9 pDevice)
{
this->SetDevice(pDevice);
this->SetSurface(NULL);
}
CXSurface::CXSurface(LPDIRECT3DDEVICE9 pDevice, const char* Path)
{
this->SetDevice(pDevice);
this->SetSurface(NULL);
this->LoadFromFile(Path);
}
CXSurface::~CXSurface()
{
if(m_Surface)
m_Surface->Release();
}
HRESULT CXSurface::LoadFromFile(const char* Path)
{
HRESULT Result = E_FAIL;
D3DXIMAGE_INFO Info;
ZeroMemory(&Info,sizeof(D3DXIMAGE_INFO));
if (SUCCEEDED(D3DXGetImageInfoFromFile(Path, &Info)))
{
Result = this->CreateSurface(Info.Width,
Info.Height,
Info.Format,
D3DPOOL_SYSTEMMEM);
}
if(Result == S_OK)
Result = D3DXLoadSurfaceFromFile(this->m_Surface, NULL, NULL,
Path, NULL, D3DX_FILTER_NONE, 0, NULL);
else
Result = E_FAIL;
return Result;
}
HRESULT CXSurface::CreateSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool)
{
if(m_Surface)
m_Surface->Release();
if(m_pDevice)
return m_pDevice->CreateOffscreenPlainSurface(Width, Height, Format,
Pool, &m_Surface, NULL);
else
return E_FAIL;
}
HRESULT CXSurface::MakeBackBuffer(void)
{
if(m_pDevice)
{
if(m_Surface)
m_Surface->Release();
return m_pDevice->GetBackBuffer(0,0, D3DBACKBUFFER_TYPE_MONO, &m_Surface);
}
else
return E_FAIL;
}
HRESULT CXSurface::PasteFromSurface(CXSurface* Source, RECT* pSourceRect, int X, int Y)
{
if((m_pDevice) && (Source))
{
POINT Point;
Point.x = X;
Point.y = Y;
return m_pDevice->UpdateSurface(Source->GetSurface(), pSourceRect,
this->m_Surface, NULL);
}
else
return E_FAIL;
}
void CXSurface::Render()
{
m_pDevice->UpdateSurface(this->GetSurface(), NULL, 0, 0);
}
</code>Sv: Fel vid programkörning
void InitD3D( HWND hWnd )
{
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
D3DPRESENT_PARAMETERS d3dpp;
memset( &d3dpp, 0, sizeof(d3dpp) );
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice );
g_Surf = new CXSurface(g_pD3DDevice);
g_Surf->LoadFromFile("bild.bmp");
}
Sedan måste du först anropa InitD3D innan du anropar UpdateWindow eftersom den kommer att orsaka ett WM_PAINT meddelande och Render anropas utan att D3D är initierat.
WinMain(...)
{
// ...
ShowWindow(hWnd, SW_SHOWDEFAULT);
InitD3D( hWnd );
UpdateWindow(hWnd);
// ...
}
Sen får det ändå inte att fungera, CreateOffscreenPlainSurface i CXSurface::CreateSurface returnerar D3DERR_INVALIDCALL hur man än gör. Förslagsvis läser du in bilden på annat sätt, t.ex. med D3DXCreateTextureFromFile. Om det är någon som kan förklara varför CreateOffscreenPlainSurface alltid misslyckas så skulle jag gärna vilja veta.
/Peter
Sv:Fel vid programkörning
D3DXCreateTextureFromFile.
CXSurface-klassen kommer från boken "DirectX 9 User Interfaces: Design and Implementation"
så den borde ju fungera.
/MagnusSv: Fel vid programkörning
LPDIRECT3DTEXTURE9 pTexture;
D3DXCreateTextureFromFile( m_pDevice, "bild.bmp", &pTexture );
/Peter
Sv:Fel vid programkörning
Jag behövde bara göra lite ändringar i main.cpp.
D3DXCreateTextureFromFile behövde jag inte använda,
det fungerade ändå.
/Magnus