texture to surface

Started by
15 comments, last by kain0015 18 years, 3 months ago
Hi! I have some problems getting my texture into a surface. The source I use atm: LPDIRECT3DSURFACE9 tmpSurface; hr = textureToInsert->GetSurfaceLevel(0, &tmpSurface); /*if(FAILED(hr)){ Err = DXGetErrorDescription9(hr); DXTRACE_MSG(Err); }*/ RECT destRect = {20, 20, 124, 124}; hr = m_lpD3DDevice->StretchRect(tmpSurface, NULL, m_lpGamefield, &destRect, D3DTEXF_NONE); if(FAILED(hr)){ Err = DXGetErrorDescription9(hr); DXTRACE_MSG(Err); } Everything works, but at StretchRect I always get a "Invalid Call" Error. Dont know whats wrong. Neither tmpSurface nor m_lpGamefield is Null. Another Question: Is it possible to create a "empty" surface? So that it's invisible? mfg
Advertisement
Have you created the surfaces using the default memory pool? Both the source surface and the destination surface has to be created with the flag D3DPOOL_DEFAULT, not using the DX managed memory pool.
yeah, tried it. But still doesnt work.
Someone told me I dont have to call the CreateOffScreenPlainSurface-Method if I get the surface via GetSurfaceLevel (Because I get a pointer).
Any other idea why it doesnt work?
Could it be a texture surface format problem, ie: incompatable formats?
Quote:Original post by devronious
Could it be a texture surface format problem, ie: incompatable formats?


Hmm... I got the texture format with D3DFMT_FROM_FILE (when i load the texture).
The surface is/was D3DFMT_A8R8G8B8.
now i changed the code:
LPDIRECT3DSURFACE9 tmpSurface;
D3DSURFACE_DESC tmpDesc;

textureToInsert->GetLevelDesc(0, &tmpDesc);

hr = m_lpD3DDevice->CreateOffscreenPlainSurface(GAMEFIELD_WIDTH_PIX, GAMEFIELD_HEIGHT_PIX, tmpDesc.Format, D3DPOOL_DEFAULT, &tmpSurface, 0);

hr = textureToInsert->GetSurfaceLevel(0, &tmpSurface);


RECT destRect = {20, 20, 124, 124};

hr = m_lpD3DDevice->StretchRect(tmpSurface, NULL, m_lpGamefield, &destRect, D3DTEXF_NONE);

so i get the format from tmpDesc.
But the StretchRect Method still failes :(
I see your using the offscreenplainsurface. This has limited stretchRectangle formats that can be used. Check the documentation for valid surface types. you'll find the table for valid types in the stretchRectangle method portion of the device namespace in direct3d.


Here's a link to the MSDN library

I'm having a hard time figuring out what your source and destination surface types are. What are they. offscreenplainsurface and ...?

[edit] please note that the compatible surface types for stretch are different when your actually changing size during copy via different sized rectangles passed to stretchRectangle.
My source-surface is tmpSurface.
with GetSurfaceLevel I put the texture into the this surface.
My target-surface is m_lpGamefield.
Here it gets Initialized:
hr = m_lpD3DDevice->CreateOffscreenPlainSurface(GAMEFIELD_WIDTH_PIX, GAMEFIELD_HEIGHT_PIX, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_lpGamefield, 0);			if(FAILED(hr)){				Err = DXGetErrorDescription9(hr);				DXTRACE_MSG(Err);				isInitialised = FALSE;			}


So, heres my whole copy-method:
BOOL Gamefield::InsertBlockIntoField(Block &toInsert, LPDIRECT3DTEXTURE9 textureToInsert){	int posX = toInsert.GetX();	int posY = toInsert.GetY();	const char* Err;	int blockWidth = toInsert.GetBlockWidth();	int blockHeight = toInsert.GetBlockWidth();	LPDIRECT3DSURFACE9 tmpSurface;	D3DSURFACE_DESC tmpDesc;	D3DSURFACE_DESC tmpDesc2;	m_lpGamefield->GetDesc(&tmpDesc);	textureToInsert->GetLevelDesc(0, &tmpDesc2);		m_lpD3DDevice->CreateOffscreenPlainSurface(tmpDesc2.Width, tmpDesc2.Height, tmpDesc.Format, tmpDesc.Pool, &tmpSurface, 0);	textureToInsert->GetSurfaceLevel(0, &tmpSurface);	RECT destRect = {20, 20, tmpDesc2.Width +20, tmpDesc2.Height +20};		hr = m_lpD3DDevice->StretchRect(tmpSurface, NULL, m_lpGamefield, &destRect, D3DTEXF_NONE);	if(FAILED(hr)){		Err = DXGetErrorDescription9(hr);		DXTRACE_MSG(Err);	}	if(tmpSurface != NULL){		tmpSurface->Release();		tmpSurface = NULL;	}	for(int i=0; i<=(blockWidth +1); i++){		for(int y=0; y<=(blockHeight+1); y++){			m_Field[posX + i][posY -3 + y] = toInsert.GetValueAtPosition(i, y);		}	}	return FALSE;}


Note: some variables are not used with current code.

I looked at the table in the msdn-lib.
Without stretching it should work. This code is without stretching but still makes problems.
I can't tell from here, but you should manually verify by walking thru the code during debug to make sure that the rectangles are identical. Or simply pass the same rec to both args in the stretchrectangle method. It will fail if any stretch.
Went throug the source via debug mode. It nowhere gets stretched. Now I tried it with fixed value (for one texture only) and it works. But now I know that it has sth to do with the size. I guess i know whats the problem.
thx :P
I had a similar problem if I remember correctly. And I think it was with A8R8G8B8 format too. I had to set the texture size symmetric, ie w = h. I was trying to set my texture to 156x48 and it was dynamic too (size would be different from time to time). I found I had to go in symmetric dimensions instead, ie 64 x 64 or 128 x 128 etc. I then switched to using twin textures. My render target was one and the texture I copied from it was the other...

[source lang=c#]            Texture rttex = new Texture(this.device, bb.Description.Width, bb.Description.Height, 1, Usage.RenderTarget, bb.Description.Format, Pool.Default);            Texture tex = new Texture(this.device, bound.rectangle.Width, bound.rectangle.Height, 1, Usage.RenderTarget, bb.Description.Format, Pool.Default);


Oh almost forgot. It crashed until I set them both to rendertargets via the constructor arg: usage.rendertarget!!!

This topic is closed to new replies.

Advertisement