On Creating a D3DX10 texture atlas

user3643
  • On Creating a D3DX10 texture atlas user3643

    I have a DirectX10 texture (ID3D10Texture2D) that I load from disk with the following code:

    CComPtr<ID3D10Device>   spD3D; // Initialized correctly elsewhere
    
    hr = D3DX10CreateTextureFromFile( 
            spD3D.p, 
            wsFilename.c_str(), 
            NULL, NULL, 
            &spTextureResource, 
            NULL 
        );
    
    if( FAILED(hr) || ! spTextureResource.p )
        return false;
    
    spTextureResource->QueryInterface <ID3D10Texture2D> ( &m_spTexture );
    if( ! m_spTexture.p )
        return false;
    

    The texture loads fine, I can blit this onscreen.

    Later, I want to use that texture as an atlas. To do so, the first thing I want to do is to call ID3D10Texture2D::Map() in order to get at the texels and parse them (to determine where my tiles are).

    The following call fails with E_INVALIDARG:

    D3D10_MAPPED_TEXTURE2D mapped;
    HRESULT hr = spTexture->Map( 0, D3D10_MAP_READ, 0, &mapped );
    

    So I'm thinking that this fails because the texture can't be read from by the CPU. So in order to get a texture that is CPU readable, I tried setting the D3DX10_IMAGE_LOAD_INFO structure to include D3D10_CPU_ACCESS_READ. This fails on D3DX10CreateShaderResourceViewFromFile() with E_INVALIDARG.

    So I guess I've given up trying to load in a texture and be able to read its data from on the CPU.

    So I thought, what about making a texture with the following D3D10_TEXTURE2D_DESC flags:

        D3D10_TEXTURE2D_DESC    desc;
        ZeroMemory(&desc, sizeof(D3D10_TEXTURE2D_DESC));
        desc.CPUAccessFlags     = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
        desc.Usage              = D3D10_USAGE_DYNAMIC;
        desc.BindFlags          = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
    

    Step 2 of my plan is to use CopyResource or CopyResourceSubregion to copy data from the disk file into my dynamic texture, so I can use the dynamic texture as a source to read texel data from.

    Will this approach work? Am I barking up the wrong tree and missing an obvious simpler route?

    I'm worried that CopyResource won't work either, since the original texture was loaded from disk without the D3D10_CPU_ACCESS_READ flag.

    God, I've got to write this for OpenGL too, I hope it's easier with GL!

    My plan is to parse this texture and determine where my tiles are, so I can use the texture as an atlas for generating sprites.

  • In order to read texel information from a texture, we need a texture with Usage = D3D10_USAGE_STAGING.

    This allows the D3D10_CPU_ACCESS_READ flag to be set.

    I loaded this texture a second time (as a temporary, or "staging" resource, so that I could read the texel information).

    So to get read access to a texture, we must fill in this IMAGE_LOAD_INFO structure, which is passed to the D3DX10CreateTextureFromFile() call.

        CComPtr<ID3D10Device>       spD3D       = RenderMgr::I()->D3DDev();
        CComPtr<ID3D10Texture2D>    spTexture;      
        CComPtr<ID3D10Resource>     spResource;
    
    
        D3DX10_IMAGE_LOAD_INFO  loadInfo;
        loadInfo.Width          = D3DX10_FROM_FILE;
        loadInfo.Height         = D3DX10_FROM_FILE;
        loadInfo.Depth          = D3DX10_FROM_FILE;
        loadInfo.FirstMipLevel  = 0;
        loadInfo.MipLevels      = D3DX10_FROM_FILE;
        loadInfo.Usage          = D3D10_USAGE_STAGING;
        loadInfo.BindFlags      = 0;
        loadInfo.CpuAccessFlags = D3D10_CPU_ACCESS_WRITE | D3D10_CPU_ACCESS_READ;
        loadInfo.MiscFlags      = 0;
        loadInfo.Format         = m_pTexAtlas->Desc().Format;
        loadInfo.Filter         = D3DX10_FILTER_NONE;
        loadInfo.MipFilter      = D3DX10_FILTER_NONE;
        loadInfo.pSrcInfo       = 0;                
    
        hr = D3DX10CreateTextureFromFile(
            spD3D,
            wsTexture.c_str(),
            &loadInfo,
            NULL,
            &spResource,
            NULL
        );
    
        if( ! SUCCEEDED(hr) )
            return false;
    
        spResource->QueryInterface <ID3D10Texture2D> (&spTexture);
        if( ! spTexture )
        {
            spResource.Release();
            return false;
        }
    
        spTexture->GetDesc( &desc );
    
        ZeroMemory(&mapped, sizeof(D3D10_MAPPED_TEXTURE2D));
    
        hr = spTexture->Map( D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ, 0, &mapped );
        if( ! SUCCEEDED(hr) )
            return false;
    

    Okay, so now the Map() call succeeds. I hope it helps someone out there !!! I wasted an entire day on this. I wish there was better documentation for dealing with textures. I was working from Luna, which like many sources, only deals with textures as they can be mapped to models :S

Tags
c++ textures windows directx10
Related questions and answers
  • ; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;iBuffer); // void* pVoid; // redefinition iBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid...) * 8; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;pBuffer); void* pVoid; // the void pointer...; bd.ByteWidth = sizeof(DWORD) * 36; bd.BindFlags = D3D10_BIND_INDEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;iBuffer); // void

  • ; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;pBuffer); void* pVoid; pBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid); //HERE memcpy(pVoid...I'm writing a simple class to draw all the debugging lines I have in my scene at once. The code in the draw loop is this so far: (If I put for example, 2 instead of temporary2DVerts.size() where I have marked with //THIS LINE, the code works fine.) when I run the code below the line breaks //HERE. Access violation reading location 0x00000000. seems like the create buffer line is not working

  • ; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;iBuffer); iBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid); // map the index buffer memcpy...}, }; // create the vertex buffer D3D10_BUFFER_DESC bd; bd.Usage = D3D10_USAGE_DYNAMIC; bd.ByteWidth = sizeof(VERTEX) * 8; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;pBuffer); void* pVoid; // the void pointer pBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid); // map the vertex buffer

  • : temp2DVerts.size(); bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;pBuffer); void* pVoid; // the void pointer pBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid); // map the vertex buffer memcpy(pVoid, &amp;temporary2DVerts[0], sizeof(temporary2DVerts[0...I want to include the drawing of other vectors of vertices in the following code, in a number of places it seems easy enough to simply add or multiply size()s of the two vectors, for instance

  • into a shader program, for use with glDrawArrays. My vertex data already exists in a VertexBufferObject that uses the following data structure to create a vertex buffer: class CustomVertex { public... object from an array of CustomVertex objects. This array is said to be interleaved. It renders successfully with the following code: void VertexBufferObject::Draw() { if( ! m_bInitialized..._TRIANGLES, m_nNumIndices, GL_UNSIGNED_INT, ((char*)NULL + 0) ); glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY

  • Alright so i'm making a vertical side scroller where you are an '8' character traveling downward while avoiding my randomly generated walls (the "generation" function) on the left and right sides... from it. As an added touch i have made it so after you collide while traveling down the randomly generated map (or rather as the walls move uppward while your character stays put) the X chars you've... destroy_shield() {shield--; if(shield<0) alive= false;} string get_name() {return name;}; string set_name(string aName) {name = aName;}; int* get_location(){return location;}; void

  • () to call stored function that generates desired object. The position of the appropriate function in the vFactories is identical to the nObjectTypeID, so I can use indexing to access the function. So...Dear all, this is going to be tough: I have created a game object factory that generates objects of my wish. However, I get memory leaks which I can not fix. Memory leaks are generated by return new Object(); in the bottom part of the code sample. static BaseObject * CreateObjectFunc() { return new Object(); } How and where to delete the pointers? I wrote bool ReleaseClassType(). Despite

  • I've decided I want to write a central ResourceManager/ResourceCache class for my hobby game engine, but am having trouble designing a caching scheme. The idea is that the ResourceManager has...) { // Calls a private method, pretend it exits T *temp = dynamic_cast<T*&gt; (_getResource(resourceId)); assert(temp != NULL); return (ResourceGuard<T>(temp... counting, it only counts when the resource is being read, (so the reference count may be 0, but an entity might still be keeping track of it's uid). It is also possible to mark resources for loading well

  • = D3D10_USAGE_DYNAMIC; bd.ByteWidth = sizeof(DWORD) * 36; bd.BindFlags = D3D10_BIND_INDEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL...; bd.ByteWidth = sizeof(VERTEX) * 8; bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; bd.MiscFlags = 0; device-&gt;CreateBuffer(&amp;bd, NULL, &amp;pBuffer); void* pVoid; // the void pointer pBuffer-&gt;Map(D3D10_MAP_WRITE_DISCARD, 0, &amp;pVoid); // map the vertex buffer memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the buffer

Data information