Jump to content
  • Advertisement
Sign in to follow this  
u235

D3DXSprite issues (texture pointer not valid)

This topic is 3809 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

I am having some difficulty getting this code to run properly. It compiles fine, but the debug info says that the texture pointer is invalid. I did some research on MSDN but couldn't find anything useful. This code is based off the tutorial on Toymaker, but I have restructured it quite a bit to be useful in a class, rather than on its own. Here is the code: SGSprite.h
#ifndef SGSPRITE_H
#define SGSPRITE_H

#include <d3d9.h>
#include <d3dx9.h>
#include <Dxerr.h>

class SGSprite
{
public:
	SGSprite(void);
	~SGSprite(void);
	void Load(char *file, LPDIRECT3DDEVICE9 device);
	void Draw();
	void SetTranslationRotationScaling(float x, float y, float rot, float scalex, float scaley);
private:
	IDirect3DTexture9 *texture;
	LPD3DXSPRITE sprite;
	D3DXVECTOR2 pos;
	D3DXVECTOR2 scaling;
	D3DXMATRIX mat;
};

#endif

SGSprite.cpp
#include "SGSprite.h"

SGSprite::SGSprite(void)
{
}

SGSprite::~SGSprite(void)
{
	sprite->Release();
}

void SGSprite::Load(char *file, LPDIRECT3DDEVICE9 device)
{
	D3DXCreateTextureFromFile(device, (LPCWSTR)file, &texture);
	D3DXCreateSprite(device, &sprite);
}

void SGSprite::Draw()
{
	sprite->SetTransform(&mat);
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	sprite->Draw(texture, NULL, NULL, NULL, 0xFFFFFFFF);
	sprite->End();
}

void SGSprite::SetTranslationRotationScaling(float x, float y, float rot, float scalex, float scaley)
{
	pos = D3DXVECTOR2(x, y);
	scaling = D3DXVECTOR2(scalex, scaley);

	D3DXMatrixTransformation2D(&mat, NULL, 0.0f, &scaling, NULL, rot, &pos);
}

I'm not sure what is going on, but what I am sure of is that the file is in the right location and that it is a power of 2. Any help is appreciated. Thanks. -AJ

Share this post


Link to post
Share on other sites
Advertisement
Try linking against D3DX9D.LIB instead of D3DX9.LIB and see if you get any debug output from D3DX.

My guess is that what YOU think of as the right place for the textures is different to what D3DX thinks. One example of when this can happen is using relative paths and making the false assumption the 'current' directory is always going to be the same as the directory your executable is in.

A related thing is forgetting that by default MSVC puts executables in \Debug or \Release folders within your project folder.

Share this post


Link to post
Share on other sites

void SGSprite::Load(char *file, LPDIRECT3DDEVICE9 device)
{
D3DXCreateTextureFromFile(device, (LPCWSTR)file, &texture);
D3DXCreateSprite(device, &sprite);
}



This right here is very, very bad. I'm guessing when you first put in the D3DXCreateTextureFromFile, the compiler complained to you because it expected an LPCWSTR (AKA const wchar_t*, a pointer to a string of Unicode characters) rather than an LPCSTR (AKA const char*, a pointer to ANSI characters). Simply casting your pointer from one type to the other will make the compiler shut up, but is wrong because you're sending one type of data while the function is expecting something completely different. Worse yet, the function has no idea that you sent it bogus data (since all it knows is the pointer type), and will happily operate on the data as if it were Unicode characters. In this case the function is probably failing since your ANSI string probably translates to nonsense in Unicode and therefore it doesn't find a file with that name existing anywhere, but in other situations this can lead to very hard-to-find bugs (notice how your program doesn't even crash, the function just fails).

Now it's completely understandable if you're confused about how Unicode and ANSI works, since typically most programmers coming from working with simple console apps have never even heard of Unicode and are used to just working with char* and std::string. I know I was pretty confused at first when I started Windows programming and had to deal with these issues myself. My advice is to do some research either at MSDN or elsewhere on how Unicode works in the Windows API (DirectX handles it almost the exact same way in most cases), or if you want I will happily explain some if it for you here. Then, I would advise picking writing your apps to only use Unicode, which means only using wchar_t* (or WCHAR* or LPWSTR), std::wstring if you're using string classes, and prepending your string literals with an "L" to make them Unicode.

Oh and in case you missed the original point...don't use casts unless you know exactly why you should be doing that cast. And if you are using casts, use the C++ style casts (static_cast, reinterpret_cast, dynamic_cast) rather than C-style casts.

Share this post


Link to post
Share on other sites
Is there a way to set the current directory, either by code or with VC project setting? Thanks.

-AJ

Share this post


Link to post
Share on other sites
The directory that your application is started in with the debugger can be set at Project Properties/Debugging/Working Directory.

Share this post


Link to post
Share on other sites
Do change the directory programmatically you can use SetCurrentDirectory.

Share this post


Link to post
Share on other sites
Thank you for calibrating me, MJP. I did not know there was a difference between the formats. I would be very gracious if you could explain the differences to me and how to use them. Thank you.

-AJ

Share this post


Link to post
Share on other sites
Just to let you guys know, due to a collaboration of your responses, I got the program running the way I meant it. So thanks very much.

-AJ

Share this post


Link to post
Share on other sites
Quote:
Original post by u235
Thank you for calibrating me, MJP. I did not know there was a difference between the formats. I would be very gracious if you could explain the differences to me and how to use them. Thank you.

-AJ


Surely. I'm running out to dinner now, but I'll write up something when I get back. In the meantime, you may want to read through this section of the Windows API documentation ---> Unicode and Character Sets (in fact pretty much all the relevent information is contained the pages that it links to, but later I'll post some of the important points in summarized form so you don't miss them).

Share this post


Link to post
Share on other sites
An LPD3DXSPRITE is a pointer to Direct3DX's sprite batching manager. Although it is confusing called a sprite, it isn't really what you would think of as a sprite - a pixel image on the screen, it's something that takes sprites, batches them for speed, and sticks them on the screen for you. The DX SDK recommends you use only one LPD3DXSPRITE for your entire program, and put all your draw calls through one Begin(), End() block.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!