Sign in to follow this  

Direct3D 9 - Sprites Not Showing

This topic is 1195 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there! I'm a beginner who's run into a bit of a bump. Despite everything seeming right (from what I can tell), Direct3D doesn't want to load any sprite I ask it to. It's definitely something I'm doing wrong, because SpriteDemo (by Frank D. Luna) works without a hitch. I can't figure out what I'm doing wrong.

 

I checked all the return values with a HRESULT, and all the functions involved in the drawing code are returning S_OK.  I also know that it's finding the path to the file correctly, as if it doesn't it will raise an access violation exception. Another person having a similar problem was told to move the camera, but that that doesn't work (nor would I expect it to, as I'm rendering in object space which uses screen coordinates [if I'm not mistaken]).

 

 

 

 

Everything else is running just fine, but the sprite isn't drawing!

 

Here's my code: 

#include "drill2class.h"

HWND mWindowHandle;


LRESULT CALLBACK WndProc(HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CLOSE:
::DestroyWindow(windowHandle);
::PostQuitMessage(0);
}
return ::DefWindowProc(windowHandle,msg,wParam,lParam);
}



bool Drill2Class::InitWindow(HINSTANCE hInstance, int nShowCmd, std::string title, int width, int height) {
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hIcon = ::LoadIcon(0,IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0,IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.lpszClassName = "Drill2";
wc.lpszMenuName = 0;

if (!RegisterClass(&wc)) {
::MessageBox(0,"Failed to register class","Error",MB_OK);
return false;
}

mWindowHandle = ::CreateWindow("Drill2",
"Drill 2 Application Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
0,
0,
hInstance,
0);
if (mWindowHandle == 0) {
::MessageBox(0,"Could not create window","Error",MB_OK);
return false;
}
::ShowWindow(mWindowHandle, nShowCmd);
::UpdateWindow(mWindowHandle);
InitDirect3D(mWindowHandle);
return true;
}

int Drill2Class::Run() {
MSG msg;
while (::GetMessage(&msg,0,0,0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}

bool Drill2Class::InitDirect3D(HWND hWnd) {
IDirect3D9* d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

D3DDISPLAYMODE mode;
d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
HRESULT deviceTypeResult; //the result returned by CheckDeviceType.


deviceTypeResult = d3d9->CheckDeviceType(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,mode.Format,mode.Format, true); 
//check preferred windowed device type

if (deviceTypeResult != S_OK) //If it isn't compatible
::MessageBox(0,"Can't use preferred device in Windowed mode", "Device Error", MB_OK);


deviceTypeResult = d3d9->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,D3DFMT_X8R8G8B8,D3DFMT_X8R8G8B8, false); 
//check preferred fullscreen device type

if (deviceTypeResult != S_OK) //if this one isn't compatible 
::MessageBox(0,"Can't use preferred device in Windowed mode", "Device Error", MB_OK);

D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, &caps);

DWORD behaviourFlags = 0;
if (caps.Caps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
behaviourFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
behaviourFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

if (caps.Caps & D3DDEVCAPS_PUREDEVICE &&
behaviourFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
behaviourFlags |= D3DCREATE_PUREDEVICE;

D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
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 = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

IDirect3DDevice9* d3dDevice = 0;
d3d9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,behaviourFlags, &d3dpp, &d3dDevice);


IDirect3DTexture9* mTex;
HRESULT theResult = D3DXCreateTextureFromFile(d3dDevice,"pinksquare.bmp",&mTex);
ID3DXSprite* mSprite;
D3DXCreateSprite(d3dDevice,&mSprite);
D3DXVECTOR3 vector3(32.0f,32.0f,32.0f);
D3DXVECTOR3 vector32(0.0f,0.0f,0.0f);





//
//

//drawing code is here

d3dDevice->BeginScene();
d3dDevice->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(128,128,128),1.0f,0);
mSprite->Begin(D3DXSPRITE_OBJECTSPACE|D3DXSPRITE_DONOTMODIFY_RENDERSTATE);
mSprite->Draw(mTex,0,&vector3,0,D3DCOLOR_XRGB(255,255,255));
mSprite->Flush();
d3dDevice->EndScene();
d3dDevice->Present(0,0,0,0);
//



return true;
}

Thanks for your help and patience! smile.png

Edited by Chunky549

Share this post


Link to post
Share on other sites

I'm rendering in object space which uses screen coordinates [if I'm not mistaken]).

 

You are mistaken. sad.png

 

The docs for the D3DXSPRITE enumeration (emphasis mine):

 

D3DXSPRITE_OBJECTSPACE The world, view, and projection transforms are not modified. The transforms currently set to the device are used to transform the sprites when the batched sprites are drawn (when Flush or End is called). If this flag is NOT specified, then world, view, and projection transforms are modified so that sprites are drawn in screen-space coordinates.

 

Your posted code doesn't mention setting the transforms.

Edited by Buckeye

Share this post


Link to post
Share on other sites

 


I'm rendering in object space which uses screen coordinates [if I'm not mistaken]).

 

You are mistaken. sad.png

 

The docs for the D3DXSPRITE enumeration (emphasis mine):

 

D3DXSPRITE_OBJECTSPACE The world, view, and projection transforms are not modified. The transforms currently set to the device are used to transform the sprites when the batched sprites are drawn (when Flush or End is called). If this flag is NOT specified, then world, view, and projection transforms are modified so that sprites are drawn in screen-space coordinates.

 

Your posted code doesn't mention setting the transforms.

 

I copied and pasted some code from Luna's example to transform the camera:

	D3DXMATRIX V;
	D3DXVECTOR3 pos(0.0f, 0.0f, -1000.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXMatrixLookAtLH(&V, &pos, &target, &up);
	d3dDevice->SetTransform(D3DTS_VIEW, &V);

	// The following code defines the volume of space the camera sees.
	D3DXMATRIX P;
	RECT R;
	GetClientRect(hWnd, &R);
	float width  = (float)R.right;
	float height = (float)R.bottom;
	D3DXMatrixPerspectiveFovLH(&P, D3DX_PI*0.25f, width/height, 1.0f, 5000.0f);
	d3dDevice->SetTransform(D3DTS_PROJECTION, &P);



		mSprite->Draw(mTex,&R,&vector3,0,D3DCOLOR_XRGB(255,255,255));
		mSprite->Flush();
		mSprite->End();
		d3dDevice->EndScene();
		d3dDevice->Present(0,0,0,0);
		//

Now a black square shows, but not the image. Do I also need to set the transform on the sprite for it to show the image?

Share this post


Link to post
Share on other sites

Edit: Problem solved! Turns out I just had to disable the lighting! Here's the code I copied from SpriteDemo of Frank D. Luna's book! Thank you very much!

 

gd3dDevice->SetRenderState(D3DRS_LIGHTING, false));

 

It works just fine now; all I had to do was set the camera and disable lighting! :)

 

To anybody else having this kind of problem:

 

1) Check the camera is set up and that the sprite is within the view of the camera.

2) Disable lighting

3) If the image is upside-down, use this code to flip it upright:

 

D3DXMATRIX mMatrix;
D3DXMatrixRotationZ(&mMatrix, D3DX_PI);
mSprite->SetTransform(&mMatrix);

Note: change mSprite to the name of your sprite object. 

Edited by Chunky549

Share this post


Link to post
Share on other sites

This topic is 1195 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this