# surface/texture scaling for a newbie

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

## Recommended Posts

This side of DirectX is totally alien for me, so I even find it difficult to ask the question, since I'm not really familiar with the terminology, but please bear with me... I'm developer of some home theatre PC software (GB-PVR), and recently decided I needed to add a custom VMR allocator/renderer to work around some limitations with the default Microsoft VMR9 components. To do this I took a Microsoft sample from the DirectX SDK and started hacking. The original sample I started with renders a scene for every video frame passed to it by VMR. It does this with BeginScene(), SetTexture/SetTextureStageState(), SetStreamSource(), SetFVF(), DrawPrimitive(), EndScene(). I've modified the sample to allow me to alpha blend a bitmap on top of this from an HBITMAP using an a additional texture I've created. Each time I need to change the bitmap (no more than once a second or so), I call pOSDTexture->LockRect() and update the raw data. I've managed to get this generally working, but the bitmap appears too large, and I'm not sure exactly what I need to do correct it. Can anyone point me in the right direction? Here is what the picture should look like: http://www.gbpvr.com/temp/osd-correct.jpg Here is what I'm getting: http://www.gbpvr.com/temp/osd-incorrect.jpg (note the OSD image is too large, so you only see the top left of the image). Here is the small 200 line piece of code I use to generate this: http://www.gbpvr.com/temp/PlaneScene.cpp Can anyone help point me in the right direction? I've been reading up on this, but I'm just confusing myself. Its also really frustrating since its only a tiny piece of code an almost doing exactly what I want... but not quite. Please help me out! Thanks [Edited by - nobber on January 20, 2006 10:56:07 PM]

##### Share on other sites
Prehaps changing,

#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 )

to:

#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )

float rhw;

to your vertex struct would help? XYZ is 3D coordinates, where as XYZRHW is screen coordinates (top left = [-1, 1] bottom right = [1, -1]).

##### Share on other sites
Thanks for the info, but no dice. I've just given those changes a go, but it was kind of a step backwards (end up with just a white screen, probably because I didnt successfully change coordinate). That said, I'm not sure what you are suggesting is actually required.

I think code is fundementally already doing the right things already as the video part is working well with 3D coordinates, but this damn bitmap I'm overlaying is just not displaying the correct size.

Any other ideas guys?

##### Share on other sites
well, instead of locking, copying, and unlocking the the surface and texture, you could try blitting the surface directly to the backbuffer.

LPDIRECT3DSURFACE9 pBACKBUFFER;DEVICE-&gt;GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBACKBUFFER );DEVICE-&gt;StretchRect( pMOVIESURFACE,                     NULL,                     pBACKBUFFER,                     NULL,                     D3DTEXF_LINEAR );

Get the backbuffer once, and StrechRect every time the frame changes.

##### Share on other sites
I'll still need to lock, copy, and unlock the the surface and texture, since the bitmap is coming from an hbitmap generated using GDI elsewhere in the application, so I need to do this get the bitmap data into the surface. This doesnt change that often though (once every second or two), so its not a huge problem.

So the video is supplied as a surface, and the bitmap is also in a surface (after lock, copy, and unlock up to a couple of seconds ago). If you look at the code, its effectively beginning the scene, rendering the video frame, then (if the OSD is currently enabled) it is also alpha blending the OSD onto the video frame, then ending the scene.

##### Share on other sites
I'm desperate to solve this guys, and working to a really tight deadline which needs to solve this before Monday.. Can anyone help further?

Please take a look at the two screen shots in the original post, and the class file.

[Edited by - nobber on January 20, 2006 10:42:29 PM]

##### Share on other sites
When is CPlaneScene::SetSrcRect being called, and what are the values of fTU and fTV? You shouldn't have to continually change these because you're always mapping the entire bitmap to the screen.

Thing is though, if the texture coordinates or vertex position data was wrong, the texture handed to your function to draw the video would be scaled or clipped incorrectly too, since you're using the same vertex data to render both textures.

Some issues that come to mind:

You should release 'pSurface' after calling D3DXLoadSurfaceFromMemory.

You should release 'backBuffer' as it's never used.

You're making three SetStreamSource, SetFVF, and DrawPrimitive calls when (I think) you should only be making two.

This line:
FAIL_RET( m_vertexBuffer->Lock(0,sizeof(pData), &pData,0) );

should be:
FAIL_RET( m_vertexBuffer->Lock(0, 0, &pData, 0) );

You should disable depth testing.

Your texture coordinates seem to be inverted along the 'v' axis, but I assume that's because your bitmap is stored in bottom-up format.

You should take the D3DLOCKED_RECT::Pitch into account when copying the bitmap data into the texture (line-by-line copy).

You should test the return value from CreateTexture, GetSurfaceLevel, and D3DXLoadSurfaceFromMemory.

Other random questions:

Is your code responsible for calling IDirect3DDevice9::Present, or does that happen in the VMR framework somewhere?

Who is responsible for setting the World, View, and Projection matrices?

Who is responsible for setting the viewport parameters?

As mentioned in a previous post, I'd also suggest using transformed vertex positions to take a possible transformation pipeline setup problem out of the equation. Doing this, your vertex position data would be in screen coordinates (0..BackBuffer.Width, 0,..BackBuffer.Height)instead of world coordinates (-1..1, -1..1).

Anyway, I hope that this at least helps you track down the problem. Sorry that I can't help you more but I've never done anything with the VMR framework so I don't know how things are setup prior to it calling your drawing functions. Good luck!

##### Share on other sites
Thanks for the help guys. I finally tracked it down to something stupid that was being done in the class that calls the one I supplied earlier. I was able to correct this issue, and it is now working correctly!

I dont really understand the full workings of it, but its doing enough for my needs.

Thanks again.

• 28
• 15
• 23
• 10
• 19