Search code examples
c++directxdirectx-9

How can I copy parts of an image from the buffer into a texture to render?


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.


Solution

  • 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}).