Sign in to follow this  
Plasmarobo

DirectX Streching X axis!?

Recommended Posts

Is there some strange problem with directX that makes it strech the X axis of textures on widescreen computers? I'm using rectangles to load animation frames and the rectangles match perfectly with the image in photoshop. However, I recently upgraded my engine core to be able to randomly place the rectangle on the image as opposed to using a static row/columns setup. It seems to work, but for some reason the coordinate system isn't matching up to the directX texture. I've debugged and everything I wrote has consistent values (the rectangles still mach up with photoshop's images). The texture is not square, but it is a power of 2. My card is fairly new, so I don't think that's the problem. My code covers several pages, but I'll post as much of it as I can, my animation classes and such.
struct cFrame2d
	{
		RECT coords; //texture position
		//int ox; //offset
		//int oy; //offset
		float duration;
		cFrame2d()
		{
			coords.left = 0;
			coords.bottom = 1;
			coords.right = 1;
			coords.top = 0;
			//ox = 0;
			//oy = 0;
			duration = 10.0f;
		}
		void operator=(const cFrame2d &rhs)
		{
			coords = rhs.coords;
			//ox = rhs.ox;
			//oy = rhs.oy;
			duration = rhs.duration;
		}
		void Save(std::ofstream &file)
		{
			file.write((char*)&coords, sizeof(RECT));
			file.write((char*)&duration, sizeof(float));
		}
		void Load(std::ifstream &file)
		{
			file.read((char*)&coords, sizeof(RECT));
			file.read((char*)&duration, sizeof(float));
		}
	};



	class cAnimData2d
	{
	protected:
		cFrame2d *m_anim; //This is the actual animation
		unsigned long size; //This is the size of the animation
		//Engine vars
		float last;
		int index;
		//bool loop; //Looping trigger
	public:
		cAnimData2d()
		{
			m_anim = new cFrame2d[1];
			size = 1;
			last = 0.0f;
			index = 0;
		}
		cAnimData2d(const cAnimData2d &rhs)
		{
			delete [] m_anim;
			size = rhs.size;
			m_anim = new cFrame2d[size];
			for(int i = 0; i < size; i++)
			{
				m_anim[i] = rhs.m_anim[i];
			}
			last = rhs.last;
			index = rhs.index;
		}
		~cAnimData2d()
		{
			delete [] m_anim;
		}

		void operator=(const cAnimData2d &rhs)
		{
			delete [] m_anim;
			size = rhs.size;
			m_anim = new cFrame2d[size];
			for(int i = 0; i < size; i++)
			{
				m_anim[i] = rhs.m_anim[i];
			}
			last = rhs.last;
			index = rhs.index;
		}
		void Start()
		{
			last = 0.0f;
			index = 0;
		}

		void Reset()
		{
			index = 0;
		}
		void Stop()
		{
			index = size;
		}
		void SetFrame(int i)
		{
			if(i >= size || i < 0)
				return;
			else
				index = i;
		}
		bool Ended()
		{
			if(index >= size)
				return true;
			else
				return false;
		}
		bool CheckDuration(float now)
		{
			if(((now-last) >= m_anim[index].duration))
				return true;
			else 
				return false;
		}

		void Update(float now)
		{
			if(CheckDuration(now) && !Ended())
			{
				++index;	
				last = now;
			}
		}
		RECT *GetFrame(float now)
		{

			if(CheckDuration(now) && !Ended())
			{
				++index;
				last = now;
			}
			if(Ended())
				return &m_anim[0].coords;
			else
				return &m_anim[index].coords;
		}
		RECT* GetFrame()
		{

			if(Ended())
				return &m_anim[0].coords;
			else
			return &m_anim[index].coords;
		}
		void Save(std::ofstream &file)
		{
			file.write((char*)&size, sizeof(unsigned long));
			for(int i = 0; i < size; i++)
			{
				m_anim[i].Save(file);
			}
		}
		void Load(std::ifstream &file)
		{
			file.read((char*)&size, sizeof(unsigned long));
			delete [] m_anim;
			m_anim = new cFrame2d[size];
			for(int i = 0; i < size; i++)
			{
				m_anim[i].Load(file);
			}
		}

		

	};
	class cAnimation2d //Holds animation information. Use an array to hold multiple animation
	{
	protected:
		cAnimData2d *m_data; //Pointer to array of animation datas
		unsigned long m_size;
	public:
		cAnimation2d()
		{
			m_data = new cAnimData2d[1];
			m_size = 1;
		}
		cAnimation2d(const cAnimation2d &rhs)
		{
			m_size = rhs.m_size;
			delete [] m_data;
			m_data = new cAnimData2d[m_size];
			for(int a = 0; a < m_size; a++)
			{
				m_data[a] = rhs.m_data[a];
			}
		}
		void operator=(const cAnimation2d &rhs)
		{
			m_size = rhs.m_size;
			delete [] m_data;
			m_data = new cAnimData2d[m_size];
			for(int a = 0; a < m_size; a++)
			{
				m_data[a] = rhs.m_data[a];
			}
		}
		~cAnimation2d()
		{
			delete [] m_data; //free data memory
			m_size = 0;
		}

		RECT* GetFrame(int index, float now) {
			if(index >= m_size || index < 0)
				return NULL;
			return m_data[index].GetFrame(now);
		}	
		RECT* GetFrame(int index)
		{
			if(index >= m_size || index < 0)
				return NULL;
			return m_data[index].GetFrame();
		}
		bool Start(int index)
		{
			if(index >= m_size || index < 0)
				return false;
			else
				m_data[index].Start();
			return true;
		}

		bool Reset(int index)
		{
			if(index >= m_size || index < 0)
				return false;
			else
				m_data[index].Reset();
			return true;
		}

		void Stop(int index){
			if(index >= m_size || index < 0)
				return;
			else
				m_data[index].Stop();
		}
		bool Check(int index)
		{
			if(index >= m_size || index < 0)
				return false;
			return m_data[index].Ended();
		}
		void Update(int index, float now)
		{
			if(index >= m_size || index < 0)
				return;
			m_data[index].Update(now);
		}
		void SetFrame(int index, int frame)
		{
			if(index >= m_size || index < 0)
				return;
			else
				m_data[index].SetFrame(frame);
		}
		RECT* LoopAnimation(int index, float now) //If an end tag is throw we just continue to run
		{
			if(index >= m_size || index < 0)
				return NULL;
			if(m_data[index].Ended())
				m_data[index].Reset();
			return m_data[index].GetFrame(now);
		}


		bool Save(LPCSTR filename)
		{
			std::ofstream file;
			file.open(filename, std::ios::binary);
			if(file.is_open())
			{
				file.write((char*)&m_size, sizeof(unsigned long));
				for(int i = 0; i < m_size; i++)
				{
					m_data[i].Save(file);
				}
				file.close();
				return true;
			}
			else
				return false;
		}
		bool Load(LPCSTR filename)
		{
			std::ifstream file;
			file.open(filename, std::ios::binary);
			if(file.is_open())
			{
				file.read((char*)&m_size, sizeof(unsigned long));
				delete [] m_data;
				m_data = new cAnimData2d[m_size];
				for(int i = 0; i < m_size; i++)
				{
					m_data[i].Load(file);
				}
				file.close();
				return true;
			}
			else
				return false;
		}
	};





those are the animation classes. Here is the rendering routine
bool CORE::cGraphics::_LoadTexture(std::string &dir)
{
	Graphics::DirectX::iTexture* texture = new Graphics::DirectX::iTexture;
	if(texture->Create(&m_D3D, dir.c_str()))
	{
		//map mode
		m_textures[dir] = texture;
		return true;
	}
	delete texture;
	texture = NULL;
	return false;
}
bool CORE::cGraphics::_RenderSprite(cBase2d *source)
{
	if(source == NULL)
		return false;
	//use typecasting here. This keeps the RSM in line 
	m_sprite.Place(source->m_x, source->m_y);
	m_sprite.Rotate(source->m_r);
	m_sprite.Scale(source->m_sx, source->m_sy);
	m_sprite.SetCenter(source->m_cx, source->m_cy);
	m_sprite.SetScaleCenter(source->m_sc);
	
	//do animtation calculations
	//set the sprite RECT to the animation index rect
	RECT *area;
	RECT rect;
	area = NULL;
	if(source->m_index != -1)
	{
	area = source->m_animation.GetFrame(source->m_index);
	if(area == NULL)
	{
		m_sprite.SetRect(NULL);
	}
	else
	{
	if(area->bottom == 0||area->right == 0)
	{
		m_sprite.SetRect(NULL);
	}
	else{
		m_sprite.SetRect(area);
	}
	}
	}
	else
	{
		m_sprite.SetRect(NULL);
	}
				
	//This sets the rect and is all we really have to do
	
	if(!m_sprite.Render(m_textures[source->m_dir])) //draws a single sprite
		return false;

	m_sprite.SetRect(NULL);
	


return true;
}





both are class based, and cBase2d holds an animation class that it uses to render a texture loaded by the texture class. I'll throw that up here too:
class iTexture
		{
		protected:
			LPDIRECT3DTEXTURE9 pTexture;
			friend class iSprite;;

		public:
			iTexture() { pTexture = NULL; }
			~iTexture() 
			{ 
				if(pTexture)
					pTexture->Release();
				pTexture = NULL;
				
			}

			bool Create(Graphics::DirectX::DirectXLayer *parent, LPCSTR file)
			{
				return SUCCEEDED(D3DXCreateTextureFromFile(parent->Device(),file,&pTexture));
			}

			bool Use(Graphics::DirectX::DirectXLayer *parent, DWORD stage = 0) 
			{ 
				return SUCCEEDED(parent->Device()->SetTexture(stage,pTexture));
			}
			
		};





for the life of me I cannot see how I broke the system I created. Sorry for the long post, but I should mention that I did have the row/column thing working using a vector to hold animation data. I figured this would be an improvement, but the X axis just hates me alot I guess. *********** Update: I did some experimenting. It seems that when the texture is square it streches it on both axises. Is it my graphics card not supporting textures larger that 512? Just for closure: It's not my card, actually, it is DirectX ensuring that I don't actually have a crappy card, and so it is forcing the texture to a square power of 2 texture by streching, rather than simply adding null pixels. [Edited by - Plasmarobo on March 9, 2008 10:30:03 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Plasmarobo
Is it my graphics card not supporting textures larger that 512?
Hard for us to say without you telling us what your card is.

Share this post


Link to post
Share on other sites
Filling a D3DCAPS9 with IDirect3DDevice9::GetDeviceCaps() allows to to inspect D3DCAPS9::MaxTextureWidth and D3DCAPS9::MaxTextureHeight if you want to check this for yourself.

GetDeviceCaps.

(I think this unlikely to be the problem though - I have ancient integrated GeForce 6-ish sort of stuff on my PC and regularly create 2048x2048 textures for atlasing onto and stuff).

Share this post


Link to post
Share on other sites

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