Solved

How do I resize a bmp file with dx9 and re position it on a window

Posted on 2010-11-20
12
616 Views
Last Modified: 2013-11-12
Hi can some show how to scale up and down a BMP file loaded via DX9 using D3DXCreateTextureFromFile(p_pd3dDevice, L"img\\NoSignal.bmp", &p_pTexture );
Once loaded I need to dynamically resize the img and reposition it on different locations on my window but not sure the best way to do this
I tried to use
D3DXMATRIX matScale;
D3DXMatrixScaling(&matScale, 1.5f, 0.5f, 0.0f);
p_pd3dDevice->SetTransform( D3DTS_WORLD, &matScale );
p_pd3dDevice->BeginScene();
p_pd3dDevice->SetTexture( 0, p_pTexture );
p_pd3dDevice->EndScene();
p_pd3dDevice->Present( NULL, NULL, NULL, NULL );

but i guess im missing code to make this work so any help or samples would be great
My image is a 2D standard BMP file
0
Comment
Question by:nchannon
  • 6
  • 6
12 Comments
 
LVL 12

Expert Comment

by:satsumo
ID: 34185071
Your code dosen't actually render anything.  Neither does it set a view or projection matrix.  Do you understand how to do these things?
0
 

Author Comment

by:nchannon
ID: 34187176
Hi thanks for the reply im new to directx moving from GDI to Directx so have to work out DIrectx9 so looking for a little help.
Basically what im trying to do is load the same image in different locations and different sizes on the one surface using the VGA card to do all the work so I would end up with for example a 4 x 4 grid each grid holding the same image the src img size would be 360 x 288 and the dst size could be anything depending on what grid layout the user selects. I then need to draw a rectangle around each image approximatly 2 px wide in white. Can do it fine in GDI but not sure what the function calls are in DX9 do acheve the same thing
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34189970
Ok, thanks for explaining.  You have quite a few things to deal with that are different to GDI.  DirectX is a 3D rendering system.  It's designed to have a camera, with a projection, looking at 3D objects.  I started explaining all the matrices for that, and then decided to go the direct route.

Firstly you need to render something.  What you are trying to do is render quads (four sided polygons, 2 triangles).  In DirectX you draw them by giving an array of vertices (one for each corner).  The vertices need to have a UV coordinate, this is defines what part of the texture is showing on this vertex (this corner of the square).

When you mention drawing a white rectangle around the images, you're still thinking GDI.  The GDI would clear the background of a HDC, DirectX does not.  You have to tell it when to clear the background and what color it should be.

The vertices I have defined draw the texture in a 64x64 square, positioned at 10, 10.  The last two numbers of each vertex are the UV coordinates.  They range from 0 to 1, so that the entire texture is drawn in the 64 x 64 square.  If they ranged them from 0 to 0.5, you would see half of the texture,  form 0 to 2 the texure would be repeated in a grid like pattern  (this is called tiling).  The number of pixels in the texure does not matter.

Anyway, rather than write an endless complex reply, I have written some code that I hope will give you a start.  Take a look at it, look up the functions used, maybe give it a go and see what happens.  Assuming something is visible try changing the coordinates in the array.  It's not the entire code you need, just a start.
typedef struct
{
   D3DXVECTOR4 p;
   D3DXVECTOR2 t;
}
QUAD_VERTEX;

QUAD_VERTEX quad[4] =
{
   {10.f, 10.f, 0.f, 1.f, 0.f, 0.f},
   {74.f, 10.f, 0.f, 1.f, 1.f, 0.f},
   {10.f, 74.f, 0.f, 1.f, 0.f, 1.f},
   {74.f, 74.f, 0.f, 1.f, 1.f, 1.f}
};

pDevice->Clear (0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff, 1.f, 0);
p_pd3dDevice->BeginScene();
pd3dDevice->SetFVF (D3DFVF_XYZRHW | D3DFVF_TEX1);
p_pd3dDevice->SetTexture (0, p_pTexture);
pd3dDevice->DrawPrimitiveUP (D3DPT_TRIANGLESTRIP, 2, quad, sizeof (QUAD_VERTEX));
p_pd3dDevice->EndScene();
p_pd3dDevice->Present (NULL, NULL, NULL, NULL);

Open in new window

0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 

Author Comment

by:nchannon
ID: 34191801
Cheers for that satsumo Ive spent most of the day looking up how to do this and what functions were what in DX9 the code you posted is what I found took alittle bit of re programming my brain but I think I got it.
Im having a little trouble manipulaiting the quad array I think I need to change it here is my code that draws a squars on the surface.
As you can see the code has int varables these hold the CRect coords for each box on the screen.
These Coords get to be populated at runtime so I need the textured_vertex data[]={
array to be dynamic so I can create multible squares position on the surface. The array is part of a for loop so each run though the loop the values change and create the new coords for the next window do you know what the best way to do this at run time is.
Thanks
struct textured_vertex{
    float x, y, z, rhw;  // The transformed(screen space) position for the vertex.
    DWORD diffuse;      // Our diffuse colour, which we'll only use for alpha
    float tu,tv;         // Texture coordinates
};
textured_vertex data[]={

 {/*left pos*/thisWinX,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,0,1},
			    {/*left pos*/thisWinX,/*top pos*/thisWinY,1,1,0xFFFFFFFF,0,0},
				{/*right pos*/thisWinWidth,/*top pos*/thisWinY,1,1,0xFFFFFFFF,1,0},
                {/*left pos*/thisWinX,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,0,1},
				{/*right pos*/thisWinWidth,/*top pos*/thisWinY,1,1,0xFFFFFFFF,1,0},
				{/*right pos*/thisWinWidth,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,1,1}

};

Open in new window

0
 
LVL 12

Expert Comment

by:satsumo
ID: 34192926
Firstly, I'm glad it helped and I'm impressed you got so far.  That really is a lot of head reprogramming.

Unless I misunderstand your comment, what you've done is really all you can do with the method I suggested.  Except you really don't need a dynamic array.  When you render the vertices, D3D copies them into its own vertex list.  You can reuse the same four vertices as often as you want.  Though again, I might be misinterpeting what your doing now.

If you're always going to show the whole texture, you could initialise the four vertices outside of the loop (the z, rhw, diffuse, tu and tv parts) and then change the x and y values inside the loop.  Render a quad each time you go around the loop.  A little less code and slightly faster.

If they were transformable vertices (D3DFVF_XYZ), they could be moved by setting the world matrix and then rendering the same vertices again.  That would be the most efficient way.  However, it would require you to set projection and view matrices too.  Something that needs a bit more head reprogramming and is easy to get wrong.
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34192990
To explain why D3D copies the vertices, it is multi-threaded.  When your code is doing all the rendering, setting matrices, loading shaders, setting textures and so on, D3D is building a long list of stuff to render.  It actually renders when you call EndScene.

The rendering is done by another thread, it sends vertices to the hardware in batches, and waits around until the hardware completes the rendering.  While that thread is rendering, you program is building another list in a different area of memory.  This way your program gets maximum processor time and the other thread ensures the hardware is working at full capacity.  Sometimes the rendering is actually queued until you call Present.
0
 

Author Comment

by:nchannon
ID: 34193106
The reason I was looking for a dynamic array was because the struct textured_vertex data[]={...}
has
 {/*left pos*/thisWinX,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,0,1},
                      {/*left pos*/thisWinX,/*top pos*/thisWinY,1,1,0xFFFFFFFF,0,0},
                        {/*right pos*/thisWinWidth,/*top pos*/thisWinY,1,1,0xFFFFFFFF,1,0},
                {/*left pos*/thisWinX,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,0,1},
                        {/*right pos*/thisWinWidth,/*top pos*/thisWinY,1,1,0xFFFFFFFF,1,0},
                        {/*right pos*/thisWinWidth,/*bottom pos*/thisWinLength,1,1,0xFFFFFFFF,1,1}

this will create one rectangle with the coords of the rectangle in the varables thisWinY thisWinLength etc if I copy this code again below ill get two rectangles providing my varables have different values which they do as they will hold the last two sets of coords at the end of the for loop statement. I need it to be dynamic because there a several different screen layouts avalible in the app the max being 32 x 32 and the minimum being 1x1 grid layout
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34193177
That's a bit clearer, though you still don't need dynamic arrays.  The code below would draw a grid of quads.  I  fixed it as a 4x4 grid, positioned the grid at [10,10], each quad is 32x32 pixels, and 40 pixels apart.  You could easily put this in a function and pass parameters.  I might also have the vertex positions arranged differently than what you intend.

textured_vertex data[]={
{0, 0, 1, 1, 0xFFFFFFFF, 0, 1},
{0, 0, 1, 1, 0xFFFFFFFF, 0, 0},
{0, 0, 1, 1, 0xFFFFFFFF, 1, 0},
{0, 0, 1, 1, 0xFFFFFFFF, 1, 1}
};

p_pd3dDevice->BeginScene();
pd3dDevice->SetFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
p_pd3dDevice->SetTexture (0, p_pTexture);

for (numRow = 0; numRow < 4; ++numRow)
{
   for (numCol = 0; numCol < 4; ++numRow)
   {
       data[0].x = 10 + numCol * 40;
       data[0].y = 10 + numRow * 40;
       data[1].x = data[0].x + 32;
       data[1].y = data[0].y;
       data[2].x = data[0].x;
       data[2].y = data[0].y + 32;
       data[3].x = data[0].x + 32;
       data[3].y = data[0].y + 32;
       d3dDevice->DrawPrimitiveUP (D3DPT_TRIANGLESTRIP, 2, data, sizeof (textured_vertex));
   }
}

p_pd3dDevice->EndScene();

Open in new window

0
 

Author Comment

by:nchannon
ID: 34196693
Hi tried your example couldnt get it to work I changed one of your for loop statments as it would never stop looping here is a basic sample of what I tried to do with your sample maybe you can see whats wrong TestDX.zip
I had to remove the rc file and ico file as the site would not allow me to upload them in the zip file the only thing in the rc file extra from standard wizard build is a button to start rendering
0
 

Author Comment

by:nchannon
ID: 34197743
ok got the sample to work I had int instead of float in the struct
0
 
LVL 12

Accepted Solution

by:
satsumo earned 500 total points
ID: 34199848
Ah yes, I see the stray int, so it works OK now?  I'm curious about the significance of  'No Signal'.
0
 

Author Comment

by:nchannon
ID: 34200362
Spoke to soon still having some issues "No Signal" is the name of the bitmap that is loaded then I try and display it in each grid layout.
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question