Note that there are some explanatory texts on larger screens.

plurals
  1. PODirectX: How to make a 2D image constantly pan / scroll in place
    primarykey
    data
    text
    <p>I am trying to find an efficient way to pan a 2D image in place using DirectX 9</p> <p>I've attached a picture below that hopefully explains what I want to do. Basically, I want to scroll the <code>tu</code> and <code>tv</code> coordinates of all the quad's vertices across the texture to produce a "scrolling in place" effect for a 2D texture.</p> <p>The first image below represents my loaded texture. The second image is the texture with the <code>tu</code>,<code>tv</code> coordinates of the four vertices in each corner showing the standard rendered image. The third image illustrates what I want to happen; I want to move the vertices in such a way that the box that is rendered straddles the end of the image and wraps back around in such a way that the texture will be rendered as shown with the two halves of the cloud separated. The fourth image shows my temporary (wasteful) solution; I simply doubled the image and pan across until I reach the far right edge, at which point I reset the vertices' tu and tv so that the box being rendered is back on the far right.</p> <p>Is there a legitimate way to do this without breaking everything into two separate quads?</p> <p><img src="https://i.stack.imgur.com/ts1Ex.png" alt="Panning Clouds"></p> <p>I've added details of my set up and my render code below, if that helps clarify a path to a solution with my current design.</p> <p>I have a function that sets up DirectX for 2D render as follows. I've added wrap properties to texture stage 0 as recommended:</p> <pre><code>VOID SetupDirectXFor2DRender() { pd3dDevice-&gt;SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); pd3dDevice-&gt;SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); pd3dDevice-&gt;SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); // Set for wrapping textures to enable panning sprite render pd3dDevice-&gt;SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); pd3dDevice-&gt;SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); pd3dDevice-&gt;SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); pd3dDevice-&gt;SetRenderState( D3DRS_ALPHAREF, 0 ); pd3dDevice-&gt;SetRenderState( D3DRS_ALPHABLENDENABLE, true ); pd3dDevice-&gt;SetRenderState( D3DRS_ALPHATESTENABLE, false ); pd3dDevice-&gt;SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); pd3dDevice-&gt;SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA) ; pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pd3dDevice-&gt;SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); return; } </code></pre> <p>On each frame, I render things as follows:</p> <pre><code>VOID RenderAllEntities() { HRESULT hResult; // Void pointer for DirectX buffer locking VOID* pVoid; hResult = pd3dDevice-&gt;Clear( 0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0 ); hResult = pd3dDevice-&gt;BeginScene(); // Do rendering on the back buffer here hResult = pd3dDevice-&gt;SetFVF( CUSTOMFVF ); hResult = pd3dDevice-&gt;SetStreamSource( 0, pVertexBuffer, 0, sizeof(CUSTOM_VERTEX) ); for ( std::vector&lt;RenderContext&gt;::iterator renderContextIndex = queuedContexts.begin(); renderContextIndex != queuedContexts.end(); ++renderContextIndex ) { // Render each sprite for ( UINT uiIndex = 0; uiIndex &lt; (*renderContextIndex).uiNumSprites; ++uiIndex ) { // Lock the vertex buffer into memory hResult = pVertexBuffer-&gt;Lock( 0, 0, &amp;pVoid, 0 ); // Copy our vertex buffer to memory ::memcpy( pVoid, &amp;renderContextIndex-&gt;vertexLists[uiIndex], sizeof(vertexList) ); // Unlock buffer hResult = pVertexBuffer-&gt;Unlock(); hResult = pd3dDevice-&gt;SetTexture( 0, (*renderContextIndex).textures[uiIndex]-&gt;GetTexture() ); hResult = pd3dDevice-&gt;DrawPrimitive( D3DPT_TRIANGLELIST, 0, 6 ); } } // Complete and present the rendered scene hResult = pd3dDevice-&gt;EndScene(); hResult = pd3dDevice-&gt;Present( NULL, NULL, NULL, NULL ); return; } </code></pre> <p>To test SetTransform, I tried adding the following (sloppy but temporary) code block inside the render code before the call to <code>DrawPrimitive</code>:</p> <pre><code>{ static FLOAT di = 0.0f; static FLOAT dy = 0.0f; di += 0.03f; dy += 0.03f; // Build and set translation matrix D3DXMATRIX ret; D3DXMatrixIdentity(&amp;ret); ret(3, 0) = di; ret(3, 1) = dy; //ret(3, 2) = dz; hResult = pd3dDevice-&gt;SetTransform( D3DTS_TEXTURE0, &amp;ret ); } </code></pre> <p>This does not make any of my rendered sprites pan about. I've been working through DirectX tutorials and reading the MS documentation to catch up on things but there are definitely holes in my knowledge, so I hope I'm not doing anything too completely brain-dead.</p> <p>Any help super appreciated.</p> <p>Thanks!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload