• Advertisement
Sign in to follow this  

texture to surface

This topic is 4427 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! 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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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?

Share this post


Link to post
Share on other sites
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 :(

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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!!!

Share this post


Link to post
Share on other sites
Quote:
Original post by devronious
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).


Yeah, thats my problem too. I guess thats the problem why it doesnt work. I'll try to make them symmetric.

Edit: Well, when I make them symmetric I have to rewrite a lot of the code... my textures only rotate only 90°. There have to be another solution *G*

[Edited by - kain0015 on January 4, 2006 5:09:55 AM]

Share this post


Link to post
Share on other sites
Notice in my last post that I didn't have to make them symmetric. That's becaused I moved away from other surface types and created two textures instead. Change from offplainsurface to a normal texture that has the rendertarget argument. But make sure that they both have the rendertarget argument set.

You should be able to set one of the textures surfaces to the device rendertarget, ie: device.SetRenderTarget(0, texture.GetSurfaceLevel(0));

[edit] prob should be more clear. Set Usage.RenderTarget when creating the textures.

[Edited by - devronious on January 4, 2006 9:23:23 AM]

Share this post


Link to post
Share on other sites
In you code, what is m_lpGameField? What do you want to do? Maybe StretchRect is not the method you need as it may stall your game. Maybe rendering the section as a sprite into other texture can do the job faster.

Luck!
Guimo


Share this post


Link to post
Share on other sites
Guimo,

Is there a way to use the same render matrices, use the same render target width and height as the normal scene, but use a smaller target that represents a rectangle in the original render area? Perhaps some sort of clipping region or such?

Thanks,

Devin

Share this post


Link to post
Share on other sites
Quote:
Original post by devronious
Notice in my last post that I didn't have to make them symmetric. That's becaused I moved away from other surface types and created two textures instead. Change from offplainsurface to a normal texture that has the rendertarget argument. But make sure that they both have the rendertarget argument set.

You should be able to set one of the textures surfaces to the device rendertarget, ie: device.SetRenderTarget(0, texture.GetSurfaceLevel(0));

[edit] prob should be more clear. Set Usage.RenderTarget when creating the textures.


Hmm... so you copy the stuff from the source texture to another (target)texture instead of a surface. Then you copied the (target)texture into the target-surface? Sorry if I didnt get you right

Share this post


Link to post
Share on other sites
Actually maybe this is wrong way for you. I rendered an object to a texture that was the same size as my screen so that I could get a duplicate of how it would render in the scene. Then copied the item from that texture to a texture that was only the size of the object image I wanted (which it's size was dynamic). From there I paint multiple copies of it into my scene via a sprite.


I could cut out a step by rendering directly to my smaller texture, but I currently don't know how and don't want to take the time to figure it out on my own. I've found that every problem has a solution it's just a matter of how long to figure it out.

-Devin

Share this post


Link to post
Share on other sites
I dont get it... if I dont rotate anything, just drawing the texture to the surface, it dont work.
But:
I dont changed the code, just got the things to add into the surface from a file (png) and it works. I used a graphic that is 52*52, i took the texturesize, etc. from the texture-object, but if I use GetSurfaceLevel it doesent work. If i load it from a file, it works.
I dont changed anything on the code!! I just replaced GetSurfaceLevel with D3DXLoadSurfaceFromFile.
The problem is that i cant rotate surfaces...

Share this post


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

  • Advertisement