Solved

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

Posted on 2010-11-20
12
612 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
 

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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
FMX enumerated colours 2 72
Fibonacci challenge 11 84
Unresolved External Symbols 3 53
White board coding practice 3 61
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
As we all know Counter Strike is a very popular computer game. Usually it is played over a network for which people create a server and users join it but it is interesting to know that one can creates a dedicated server which not only hosts the game…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
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.

760 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now