Advertisement Jump to content
Sign in to follow this  
d07RiV

Rendering textured quads with DX10/11

This topic is 1774 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I haven't used dx10/11 before, and I need to port a simple dx9 code that creates textures from memory and renders then on screen.
 
The device already exists, I need to change all the flags to do my 2d rendering and change them back afterwards. Here's roughly what my dx9 code does:
 
Main rendering function
void onRender(...)
{

  if (pOrigState == NULL && !SUCCEEDED(pDevice->CreateStateBlock(D3DSBT_ALL, &pOrigState)))
    return;

  pOrigState->Capture();

  D3DVIEWPORT9 oldViewport;
  IDirect3DBaseTexture9* oldTexture;

  pDevice->GetViewport(&oldViewport);
  pDevice->GetTexture(0, &oldTexture);

  if (pNewState == NULL)
  {
    pDevice->BeginStateBlock();

    pDevice->SetFVF(VertexFVF);
    pDevice->SetVertexShader(NULL);
    pDevice->SetPixelShader(NULL);

    pDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    pDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
    pDevice->SetRenderState(D3DRS_WRAP0, 0);
    pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
    pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0F);
    pDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

    pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_PYRAMIDALQUAD);
    pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_PYRAMIDALQUAD);
    pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

    pDevice->EndStateBlock(&pNewState);
  }
  pNewState->Apply();

  // rendering goes here

  pDevice->SetViewport(&oldViewport);
  pDevice->SetTexture(0, oldTexture);
  pOrigState->Apply();
}
Rendering uses three procedures - create/update a texture from memory, set viewport, and render a quad.

For loading textures, I create a D3DPOOL_SYSTEMMEM texture for all power-of-two square sizes and use them to update D3DPOOL_DEFAULT textures that are used for actual rendering.

Drawing a rectangle:
void drawRect(...)
{
  pDevice->SetTexture(0, pTexture);
  vertices[0].x = x0; vertices[0].y = y0; vertices[0].color = color;
  vertices[1].x = x1; vertices[1].y = y0; vertices[1].color = color;
  vertices[2].x = x1; vertices[2].y = y1; vertices[2].color = color;
  vertices[3].x = x0; vertices[3].y = y1; vertices[3].color = color;
  vertices[0].u = 0; vertices[0].v = 0;
  vertices[1].u = u; vertices[1].v = 0;
  vertices[2].u = u; vertices[2].v = v;
  vertices[3].u = 0; vertices[3].v = v;
  pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertices, sizeof(Vertex));
}
Now, I'm looking for the bare minimum DX10/11 code that would do the same thing. I put something together looking at tutorials, but its pretty ugly and I'm hoping there's something simpler.

Texture loading seems to work fine, and is probably even easier than DX9 since I only need to call Map or UpdateSubResource once.

However, setting up render states and rendering a quad requires too much work.. Here's roughly what I have now, in no particular order:
  struct Vertex
  {
    float x, y, z, w;
    float u, v;
    unsigned long color;
  };
// VS
  struct vst {
    float4 pos: POSITION;
    float2 tex: TEXCOORD0;
    float4 clr: COLOR;
  };
  struct pst {
    float4 pos: SV_POSITION;
    float2 tex: TEXCOORD0;
    float4 clr: COLOR;
  };
  pst VS(vst i) {
    pst o;
    o.pos = i.pos;
    o.tex = i.tex;
    o.clr = i.clr;
    return o;
  };
// PS
  Texture2D tex;
  SamplerState ss;
  struct pst {
    float4 pos: POSITIONT;
    float2 tex: TEXCOORD0;
    float4 clr: COLOR;
  };
  float4 PS(pst i): SV_TARGET {
    return tex.Sample(ss, i.tex) * i.clr;
  };
// vertex declaration
  D3D11_INPUT_ELEMENT_DESC desc[3];
  memset(desc, 0, sizeof desc);
  desc[0].SemanticName = "POSITION";
  desc[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
  desc[0].AlignedByteOffset = 0;
  desc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  desc[1].SemanticName = "TEXCOORD";
  desc[1].Format = DXGI_FORMAT_R32G32_FLOAT;
  desc[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  desc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
  desc[2].SemanticName = "COLOR";
  desc[2].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  desc[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
  desc[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
With this I'm getting random triangles on the screen that change from frame to frame, no idea what's going on there. Ideally I would like to avoid vertex transformation so I can use screen coordinates (0..width) instead of (-1..1), but using POSITIONT semantic results in nothing on the screen at all. Is there any way to debug what's going on in the pipeline? Edited by d07RiV

Share this post


Link to post
Share on other sites
Advertisement

I'd prefer to stay away from such libraries since its going in a DLL and footprint size is fairly important.

Anyway thanks for the link I'll see if I can make anything useful out of their source code. SpriteBatch seems like the thing I need, I'll try to minimize the code.

 

Is there anything similar to XYZRHW in d3d11 to bypass viewport transform so I can specify screen coordinates along with a passthrough VS? Also, if I change the viewport,

will the (-1,1) still be mapped to the whole window (and subsequently clipped) or to the new viewport?

Edited by d07RiV

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!