0

I have been searching around for a simple solution, but I have not found anything. Currently I am loading a texture from a file and rendering it into the buffer using C++ 2012 Express DirectX9. But what I want to do is be able to copy parts of the buffer, and use the part that is copied as the texture, instead of the loaded texture.

I want to be able to copy/select like a map-editor would do.

EDIT: Problem Solves :) It was just dumb mistakes.

User
  • 659
  • 2
  • 12
  • 29
  • I think you should look into rendering into texture, then use some part of that texture to use at the later rendering - if I understand correctylu what you want to achive – marcinj Dec 28 '12 at 23:35
  • @marcin_j Hmm, could you further explain? I have updated my code to show what I am trying to do. – User Dec 29 '12 at 15:34
  • Can you describe how you render the image? Do you render each tile as a quad with a texture applied? Do you use fixed pipeline or custom shaders? – miloszmaki Dec 29 '12 at 17:55
  • @miloszmaki I updated my code. What I do is I make a vector of the area in 32x32 cells for each window, and then from there I can calculate which cell the mouse is at to draw to. I also want to use this to select a 32x32 cell from the pallet window... – User Dec 29 '12 at 18:06

1 Answers1

0

You can use the StretchRect function (see documentation).

You should copy a subset of the source buffer into the whole destination buffer (which is the new texture's buffer in your case). Something like this:

LPDIRECT3DTEXTURE9 pTexSrc,     // source texture
                   pTexDst;     // new texture (a subset of the source texture)

// create the textures
// ...

LPDIRECT3DSURFACE9 pSrc, pDst;

pTexSrc->GetSurfaceLevel(0, &pSrc);
pTexDst->GetSurfaceLevel(0, &pDst);

RECT rect;   // (x0, y0, x1, y1) - coordinates of the subset to copy
rect.left = x0;
rect.right = x1;
rect.top = y0;
rect.bottom = y1;

pd3dDevice->StretchRect(pSrc, &rect, pDst, NULL, D3DTEXF_NONE);
// the last parameter could be also D3DTEXF_POINT or D3DTEXF_LINEAR

pSrc->Release();
pDst->Release(); // remember to release the surfaces when done !!!

EDIT:

OK, I've just got through the tones of your code and I think the best solution would be to use uv coordinates instead of copying subsets of the palette texture. You should calculate the appropriate uv coordinates for a given tile in game_class:: game_gui_add_current_graphic and use them in the CUSTOMVERTEX structure:

float width; // the width of the palette texture
float height; // the height of the palette texture
float tex_x, tex_y; // the coordinates of the upper left corner
                    // of the palette texture's subset to use for
                    // the current tile texturing
float tex_w, tex_h; // the width and height of the above mentioned subset

float u0, u1, v0, v1;
u0 = tex_x / width;
v0 = tex_y / height;
u1 = u0 + tex_w / width;
v1 = v0 + tex_h / height;

// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX vertices[] = {
{ 0.0f, 32.0f, 1.0f, u0, v1, D3DCOLOR_XRGB(255, 0, 0), },
{ 0.0f, 0.0f, 1.0f, u0, v0, D3DCOLOR_XRGB(255, 0, 0), },
{ 32.0f, 32.0f, 1.0f, u1, v1, D3DCOLOR_XRGB(0, 0, 255), },    
{ 32.0f, 0.0f, 1.0f, u1, v0, D3DCOLOR_XRGB(0, 255, 0), } };

Example: Your palette consists of 3 rows and 4 columns with the 12 possible cell textures. Each texture is 32 x 32. So tex_w = tex_h = 32;, width = 4 * tex_w; and height = 3 * tex_h;. Suppose you want to calculate uv coordinates for a tile which should be textured with the image in the second row and the third column of the palette. Then tex_x = (3-1)*tex_w; and tex_y = (2-1)*tex_h;. Finally, you calculate the UVs as in the code above (in this example you'll get {u0,v0,u1,v1} = {(3-1)/4, (2-1)/3, 3/4, 2/3} = {0.5, 0.33, 0.75, 0.66}).

miloszmaki
  • 1,635
  • 15
  • 21
  • Seems to crash when calling GetSurfaceLevel – User Dec 28 '12 at 23:19
  • You have to create the textures first. Use `D3DXCreateTextureFromFile` for your first texture and `D3DXCreateTexture` for the destination texture. – miloszmaki Dec 28 '12 at 23:59
  • Yes, I figured that out just now. However, how can I copy the texture over to another texture? – User Dec 29 '12 at 00:01
  • `StretchRect` is just doing that. It copies a subset of the source texture into the destination texture. You just need to specify the subset's coordinates in `rect`. – miloszmaki Dec 29 '12 at 00:02
  • Yes, but I need to copy it to a new texture so I can store it into a vector, so then I can go through the vector to render each x,y location – User Dec 29 '12 at 00:08
  • Seems as if the texture is just black. – User Dec 29 '12 at 00:40
  • You need to specify `D3DUSAGE_RENDERTARGET` while creating the destination texture. `StretchRect` doesn't support texture to texture copying unless the destination texture is a render target texture. Also, if you don't need mipmaps, pass `1` instead of `0` as the third parameter to the `CreateTexture` function. – miloszmaki Dec 29 '12 at 12:23
  • Okay, I understand somewhat. I have updated my post with exactly what I am doing. Thanks for all the help! – User Dec 29 '12 at 15:27
  • Remember to release the surfaces once the stretching is done! By the way, can't you just use the UV coordinates to access the proper texture from the palette (texture atlas) instead of doing many redundant copies of the texture's subsets? – miloszmaki Dec 29 '12 at 17:41
  • Still not working, its still black! Any other thoughts? Edit: I dont know how to do that, but if it would be easier, then sure... – User Dec 29 '12 at 17:48
  • I think you should texture each tile with the whole palette texture and just set the appropriate uv coordinates, so that the tile is textured with a subset of the texture. I've edited the answer, check it out. – miloszmaki Dec 29 '12 at 20:16
  • Ahhh, i see what you are saying. Hmm, why isnt the other way working though? – User Dec 30 '12 at 03:54
  • I don't know, it should also work. Probably you have some bugs with the textures copying and rendering. – miloszmaki Dec 30 '12 at 15:24
  • how would I render with the above edit? I guess i just dont understand fully :( – User Dec 30 '12 at 17:09
  • You should render each tile as four `CUSTOMVERTEX` vertices just like you did in your code, but with the appropriate uv coordinates. You need to apply only one texture for each tile, which is the whole palette texture. The uv coordinates will make the tiles being textured with the correct subset of the palette. Remember to specify `D3DFVF_TEX1` in your `D3DFVF_CUSTOMVERTEX`. – miloszmaki Dec 30 '12 at 19:22
  • Hm, its not really working, its showing the "hand" as the whole image still (not a 32x32 ) I am loading a big image now into the pallet. – User Dec 30 '12 at 19:31
  • I got it working miloszmaki, but its only doing the upper 32x32 cell :/ – User Dec 30 '12 at 20:42
  • I figured it out, but now it seems like i am loosing texture details Oo. Thanks though you helped enough! – User Dec 30 '12 at 21:49