Jump to content
  • Advertisement
Sign in to follow this  
blueshogun96

OpenGL D3DXMatrixOrthoLH for 2D rendering

This topic is 2517 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've been trying to set up an orthographic projection for Direct3D so I can port this graphic effect that was originally written for OpenGL. My problem is that I can't get D3DXMatrixOrthoLH to work to save my life. The original code was set up to use an orthographic projection, and shouldn't be this difficult to deal with.

I really hate to just throw a heap of code at you all, but I think if I posted the original code and the more important parts of mine, maybe it will make more sense:

IDirect3DTexture9* g_pSlidingImageTexture = NULL;
CProgrammablePixelShader* g_pSlidingImagePS = NULL;
stSlidingImage Images[MAXSLIDINGIMAGES];

struct SLIDINGIMAGEVERTEX
{
D3DXVECTOR3 vecPosition;
D3DXVECTOR2 vecTexture;

static DWORD FVF;
};

DWORD SLIDINGIMAGEVERTEX::FVF = (D3DFVF_XYZ | D3DFVF_TEX1);



static float frand(float min, float max)
{
return min + ((max - min) * (float)rand() / (float)RAND_MAX);
}

HRESULT SlidingImages_Build()
{
// Find the base texture
HRESULT hr = D3DXCreateTextureFromFile( g_pD3DDevice,
effect_api::GetFilePath( "swamp.tga" ).c_str(), &g_pSlidingImageTexture );
if( FAILED( hr ) )
return hr;

// Find the necessary pixel shader (if not found already)
if( g_pSlidingImagePS == NULL )
{
g_pSlidingImagePS = (CProgrammablePixelShader*) ShaderManager_GetShader( "ps_texdiffuse.pso", SHADERTYPE_PIXEL );
if( !g_pSlidingImagePS )
return E_FAIL;
}

// Reset images
for (int i = 0; i < MAXSLIDINGIMAGES; i++)
{
Images.speed = 1.0f / 1600.0f + frand(0, 1.0f)/1600.0f;
Images.u = frand(-0.05f, 1.0f);
Images.x = Images.u * 2.0f - 1.0f;
Images.y = frand(-1.0f, 1.0f);
Images.v = Images.y / 2.0f + 0.45f;
}

return hr;
}

void SlidingImages_Update(float elapTime)
{
for (int i = 0; i < MAXSLIDINGIMAGES; i++)
{
Images.u += Images.speed;

if (Images.u > 1.1f)
{
Images.u = -0.05f;
Images.x = Images.u * 2.0f - 1.0f;
Images.y = frand(-1.0f, 1.0f);
Images.v = Images.y / 2.0f + 0.45f;
Images.speed = 1.0f / 1600.0f + frand(0, 1.0f)/1600.0f;
}
else
{
Images.x = Images.u * 2.0f - 1.0f;
}
}
}

void SlidingImages_Draw(float elapTime)
{
D3DXMATRIX mtxWorld, mtxView, mtxProjection;
D3DXMATRIX mtxOldProjection, mtxIdentity, mtxTranslation;

// Disable depth testing and lighting
g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

// Enable alpha blending
g_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
g_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
g_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

// Save the old matrices
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &mtxOldProjection );
g_pD3DDevice->GetTransform( D3DTS_WORLD, &mtxWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &mtxView );

// Set orthographic projection matrix and leave the world*view (modelview)
// matrix to the identity.
D3DXMatrixOrthoRH( &mtxProjection, 640.0f, 480.0f, 0.0f, 1.0f );
D3DXMatrixIdentity( &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_WORLD, &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_VIEW, &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &mtxProjection );

//Were using the ortho view so remeber that it's -1 <---> 1 for values of x and y
D3DXVECTOR4 vecColour( 0.5f, 0.5f, 0.5f, 0.75f);
// D3DXMatrixTranslation( &mtxTranslation, 0.0f, 0.0f, 0.1f );
// g_pD3DDevice->SetTransform( D3DTS_WORLD, &mtxTranslation );

// Set the texture
g_pD3DDevice->SetTexture( 0, g_pSlidingImageTexture );

// Enable the pixel shader
// g_pSlidingImagePS->Enable();
// Set the diffuse colour in constant 0
// g_pD3DDevice->SetPixelShaderConstantF( 0, (float*) &vecColour, 1 );

static float scroll = 0.0f;
scroll += 0.001f;

for (int i = 0; i < MAXSLIDINGIMAGES; i++)
{
SLIDINGIMAGEVERTEX v[4];

// sin's / cos's are thrown in to spice us the background texture...
v[0].vecTexture = D3DXVECTOR2(Images.u + sinf(scroll), Images.v + cosf(scroll) );
v[0].vecPosition = D3DXVECTOR3(Images.x - 0.1f, Images.y - 0.1f, 0.0);
v[1].vecTexture = D3DXVECTOR2(Images.u + 0.1f + sinf(scroll), Images.v + cosf(scroll) );
v[1].vecPosition = D3DXVECTOR3(Images.x + 0.1f, Images.y - 0.1f, 0.0);
v[2].vecTexture = D3DXVECTOR2(Images.u + 0.1f + sinf(scroll), Images.v + 0.1f + cosf(scroll));
v[2].vecPosition = D3DXVECTOR3(Images.x + 0.1f, Images.y + 0.1f, 0.0);
v[3].vecTexture = D3DXVECTOR2(Images.u + sinf(scroll), Images.v + 0.1f + cosf(scroll));
v[3].vecPosition = D3DXVECTOR3(Images.x - 0.1f, Images.y + 0.1f, 0.0);

g_pD3DDevice->SetFVF( SLIDINGIMAGEVERTEX::FVF );
g_pD3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, v, sizeof( SLIDINGIMAGEVERTEX ) );
}

// TODO: Draw outline with liens
/*glDisable( GL_BLEND );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glBegin(GL_QUADS);

for (int i = 0; i < MAXSLIDINGIMAGES; i++)
{
// sin's / cos's are thrown in to spice us the background texture...
glTexCoord2f(Images.u + sinf(scroll), Images.v + cosf(scroll) ); glVertex3f(Images.x - 0.1f, Images.y - 0.1f, 0.0);
glTexCoord2f(Images.u + 0.1f + sinf(scroll), Images.v + cosf(scroll) ); glVertex3f(Images.x + 0.1f, Images.y - 0.1f, 0.0);
glTexCoord2f(Images.u + 0.1f + sinf(scroll), Images.v + 0.1f + cosf(scroll)); glVertex3f(Images.x + 0.1f, Images.y + 0.1f, 0.0);
glTexCoord2f(Images.u + sinf(scroll), Images.v + 0.1f + cosf(scroll)); glVertex3f(Images.x - 0.1f, Images.y + 0.1f, 0.0);
}

glEnd();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );*/

// Disable the pixel shader
// g_pSlidingImagePS->Disable();

// Restore old matrices
g_pD3DDevice->SetTransform( D3DTS_WORLD, &mtxWorld );
g_pD3DDevice->SetTransform( D3DTS_VIEW, &mtxView );
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &mtxOldProjection );

// Restore previous render states (except lighting)
g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
g_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}


The original code can be found here (scroll down to the "Sliding Images" sample): http://www.walterreid.com/opengl

I've been at this for quite a while and I can't seem to figure out what I'm doing wrong here. Hopefully this explains the problem well enough. This sucks. Any ideas? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Bump.

I even tried writing some very minimal code to test the orthographic projection. No matter what I do....

It just.
Doesn't.
Work.


D3DXMATRIX mtxIdentity, mtxProjection;

D3DXMatrixOrthoLH( &mtxProjection, 640, 480, 0.0f, 1.0f );
D3DXMatrixIdentity( &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_WORLD, &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_VIEW, &mtxIdentity );
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &mtxProjection );

D3DXVECTOR3 v[4];
float w = 128.0f, h = 64.0f;
v[0].x = v[3].x = -w/2.0f;
v[1].x = v[2].x = w/2.0f;
v[0].y = v[1].y = h/2.0f;
v[2].y = v[3].y = -h/2.0f;
v[0].x = v[1].z = v[2].z = v[3].z = 1.0f;

g_pD3DDevice->SetFVF( D3DFVF_XYZ );
g_pD3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, v, sizeof( D3DXVECTOR3 ) );

Share this post


Link to post
Share on other sites
Coming from OpenGL code you'll probably find that D3DXMatrixOrthoOffCenterRH is more like what you need. This should give you the exact same result as you get with OpenGL (aside from the top-left/bottom-left difference, which will just mean that your image will be upside-down on screen - exchange the b and t params to correct it.).

Share this post


Link to post
Share on other sites
Here's a fairly minimal set of code for rendering with OrthoOffCenterRH; can you plug this into your program and confirm whether or not it works for you (you'll need to change some variable names):

void RenderScene (void)
{
    // i created it with depth and stencil (even though i don't use them) so i clear them here too
    d3d_Device->Clear (0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL | D3DCLEAR_TARGET, 0x00000000, 1.0f, 1);

    d3d_Device->SetRenderState (D3DRS_LIGHTING, FALSE);

    d3d_Device->BeginScene ();

    D3DXMATRIX m;

    D3DXMatrixIdentity (&m);

    d3d_Device->SetTransform (D3DTS_WORLD, &m);
    d3d_Device->SetTransform (D3DTS_VIEW, &m);

    // i just created the window at this size
    D3DXMatrixOrthoOffCenterRH (&m, 0, 800, 600, 0, 0, 1);

    d3d_Device->SetTransform (D3DTS_PROJECTION, &m);

    // float xyz[3]; DWORD color;
    MYWONDERFULVERTEX verts[] =
    {
        100, 100, 0, 0xffffffff,
        600, 100, 0, 0xffffffff,
        600, 400, 0, 0xffffffff,
        100, 400, 0, 0xffffffff
    };

    d3d_Device->SetFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE);
    d3d_Device->DrawPrimitiveUP (D3DPT_TRIANGLEFAN, 2, verts, sizeof (MYWONDERFULVERTEX));

    d3d_Device->EndScene ();

    d3d_Device->Present (NULL, NULL, NULL, NULL);
}

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!