[SOLVED] Can't get expected result. It's perspective problem?

Started by
4 comments, last by geniys 14 years, 3 months ago
Can't get expected result. It's perspective problem? Hi. I just using Direct3D. I write some code to get expected shape image. (below image link) http://img442.imageshack.us/img442/6761/expected.png But I get this result (below image link) http://img706.imageshack.us/img706/8733/unexpected.png I think, it's result of wrong behavior of Z-buffer. But isn't. I can't find way to solve this problem. I want to use perspective effect. Help Plz. This is full code.


#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include <strsafe.h>
#pragma warning( default : 4996 )

// A structure for our custom vertex type
struct VERTEX
{
    FLOAT x, y, z;
	FLOAT nx, ny, nz;
};

// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)


#pragma warning( disable : 4305 )
VERTEX g_vertices[] = 
{
{ -1,	-1,	1,	-0,	-0.894427,	-0.447214 },
{ 1,	-1,	1,	-0,	-0.894427,	-0.447214 },
{ 0.5,	-0.5,	0,	-0,	-0.894427,	-0.447214 },
{ 0.5,	-0.5,	0,	0,	-0.894427,	-0.447214 },
{ -0.5,	-0.5,	0,	0,	-0.894427,	-0.447214 },
{ -1,	-1,	1,	0,	-0.894427,	-0.447214 },
{ -0.5,	-0.5,	0,	0,	0.894427,	-0.447214 },
{ 0.5,	-0.5,	0,	0,	0.894427,	-0.447214 },
{ 0,	0,	1,	0,	0.894427,	-0.447214 },
{ 1,	-1,	1,	0.894427,	0,	-0.447214 },
{ 1,	1,	1,	0.894427,	0,	-0.447214 },
{ 0.5,	0.5,	0,	0.894427,	0,	-0.447214 },
{ 0.5,	0.5,	0,	0.894427,	0,	-0.447214 },
{ 0.5,	-0.5,	0,	0.894427,	0,	-0.447214 },
{ 1,	-1,	1,	0.894427,	0,	-0.447214 },
{ 0.5,	-0.5,	0,	-0.894427,	-0,	-0.447214 },
{ 0.5,	0.5,	0,	-0.894427,	-0,	-0.447214 },
{ 0,	0,	1,	-0.894427,	-0,	-0.447214 },
{ 1,	1,	1,	0,	0.894427,	-0.447214 },
{ -1,	1,	1,	0,	0.894427,	-0.447214 },
{ -0.5,	0.5,	0,	0,	0.894427,	-0.447214 },
{ -0.5,	0.5,	0,	0,	0.894427,	-0.447214 },
{ 0.5,	0.5,	0,	0,	0.894427,	-0.447214 },
{ 1,	1,	1,	0,	0.894427,	-0.447214 },
{ 0.5,	0.5,	0,	0,	-0.894427,	-0.447214 },
{ -0.5,	0.5,	0,	0,	-0.894427,	-0.447214 },
{ 0,	0,	1,	0,	-0.894427,	-0.447214 },
{ -1,	1,	1,	-0.894427,	0,	-0.447214 },
{ -1,	-1,	1,	-0.894427,	0,	-0.447214 },
{ -0.5,	-0.5,	0,	-0.894427,	0,	-0.447214 },
{ -0.5,	-0.5,	0,	-0.894427,	-0,	-0.447214 },
{ -0.5,	0.5,	0,	-0.894427,	-0,	-0.447214 },
{ -1,	1,	1,	-0.894427,	-0,	-0.447214 },
{ -0.5,	0.5,	0,	0.894427,	0,	-0.447214 },
{ -0.5,	-0.5,	0,	0.894427,	0,	-0.447214 },
{ 0,	0,	1,	0.894427,	0,	-0.447214 },
{ -1,	-1,	1,	0,	-0.894427,	0.447214 },
{ 0.5,	-0.5,	2,	0,	-0.894427,	0.447214 },
{ 1,	-1,	1,	0,	-0.894427,	0.447214 },
{ 0.5,	-0.5,	2,	0,	-0.894427,	0.447214 },
{ -1,	-1,	1,	0,	-0.894427,	0.447214 },
{ -0.5,	-0.5,	2,	0,	-0.894427,	0.447214 },
{ -0.5,	-0.5,	2,	0,	0.894427,	0.447214 },
{ 0,	0,	1,	0,	0.894427,	0.447214 },
{ 0.5,	-0.5,	2,	0,	0.894427,	0.447214 },
{ 1,	-1,	1,	0.894427,	0,	0.447214 },
{ 0.5,	0.5,	2,	0.894427,	0,	0.447214 },
{ 1,	1,	1,	0.894427,	0,	0.447214 },
{ 0.5,	0.5,	2,	0.894427,	0,	0.447214 },
{ 1,	-1,	1,	0.894427,	0,	0.447214 },
{ 0.5,	-0.5,	2,	0.894427,	0,	0.447214 },
{ 0.5,	-0.5,	2,	-0.894427,	0,	0.447214 },
{ 0,	0,	1,	-0.894427,	0,	0.447214 },
{ 0.5,	0.5,	2,	-0.894427,	0,	0.447214 },
{ 1,	1,	1,	0,	0.894427,	0.447214 },
{ -0.5,	0.5,	2,	0,	0.894427,	0.447214 },
{ -1,	1,	1,	0,	0.894427,	0.447214 },
{ -0.5,	0.5,	2,	0,	0.894427,	0.447214 },
{ 1,	1,	1,	0,	0.894427,	0.447214 },
{ 0.5,	0.5,	2,	0,	0.894427,	0.447214 },
{ 0.5,	0.5,	2,	0,	-0.894427,	0.447214 },
{ 0,	0,	1,	0,	-0.894427,	0.447214 },
{ -0.5,	0.5,	2,	0,	-0.894427,	0.447214 },
{ -1,	1,	1,	-0.894427,	0,	0.447214 },
{ -0.5,	-0.5,	2,	-0.894427,	0,	0.447214 },
{ -1,	-1,	1,	-0.894427,	0,	0.447214 },
{ -0.5,	-0.5,	2,	-0.894427,	0,	0.447214 },
{ -1,	1,	1,	-0.894427,	0,	0.447214 },
{ -0.5,	0.5,	2,	-0.894427,	0,	0.447214 },
{ -0.5,	0.5,	2,	0.894427,	0,	0.447214 },
{ 0,	0,	1,	0.894427,	0,	0.447214 },
{ -0.5,	-0.5,	2,	0.894427,	0,	0.447214 },
};
#pragma warning( default : 4305 )

const UINT g_numVertex = sizeof(g_vertices) / sizeof(VERTEX);

LPDIRECT3D9             g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold Vertices

HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // Set up the structure used to create the D3DDevice
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.EnableAutoDepthStencil	= TRUE;
	d3dpp.AutoDepthStencilFormat	= D3DFMT_D16;

    // Create the D3DDevice
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Device state would normally be set here
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,	D3DCULL_CW);
	g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,		D3DZB_TRUE);
	g_pd3dDevice->SetRenderState(D3DRS_ZFUNC,		D3DCMP_LESSEQUAL);
	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,	FALSE);

    return S_OK;
}

HRESULT InitVB()
{
	if( FAILED( g_pd3dDevice->CreateVertexBuffer( g_numVertex * sizeof( VERTEX ), 0, 
													D3DFVF_VERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    VOID* pVertices;
	if( FAILED( g_pVB->Lock( 0, sizeof( g_vertices ), ( void** )&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, g_vertices, sizeof( g_vertices ) );
    g_pVB->Unlock();

    return S_OK;
}

VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}

VOID SetupLights()
{
    D3DMATERIAL9 mtrl;
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = 1.0f;
    mtrl.Diffuse.g = 1.0f;
    mtrl.Diffuse.b = 1.0f;
    mtrl.Diffuse.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );

    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = 1.0f;
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
	light.Diffuse.a = 1.0f;
    vecDir = D3DXVECTOR3( -1.0f, -0.5f, 0.2f);
    D3DXVec3Normalize( ( D3DXVECTOR3* )&light.Direction, &vecDir );
    light.Range = 1000.0f;
    g_pd3dDevice->SetLight( 0, &light );
    g_pd3dDevice->LightEnable( 0, TRUE );

    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}

VOID SetupMatrices()
{
    D3DXMATRIXA16 matWorld;
	D3DXMatrixIdentity(&matWorld);
	D3DXMatrixRotationY(&matWorld, D3DXToRadian(45));	
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

    D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-20.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(20), 1, -100, 10);	// unexpected shape
	D3DXMatrixOrthoLH(&matProj, 10, 10, -1, 100);							// expected shape
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

VOID Render()
{
	// Clear the backbuffer to a blue color
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );

    // Begin the scene
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
		// Setup the Lights and materials
        SetupLights();

		// Setup the world, view, and projection Matrices
        SetupMatrices();

        // Draw the triangles in the vertex buffer. This is broken into a few
        // steps. We are passing the Vertices down a "stream", so first we need
        // to specify the source of that stream, which is our vertex buffer. Then
        // we need to let D3D know what vertex shader to use. Full, custom vertex
        // shaders are an advanced topic, but in most cases the vertex shader is
        // just the FVF, so that D3D knows what type of Vertices we are dealing
        // with. Finally, we call DrawPrimitive() which does the actual rendering
        // of our geometry (in this case, just one triangle).
		g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( VERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_VERTEX );
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, g_numVertex / 3 );

        // End the scene
        g_pd3dDevice->EndScene();
    }

    // Present the backbuffer contents to the display
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    // Register the window class
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 02: Vertices",
                              WS_OVERLAPPEDWINDOW, 100, 100, 400, 400,
                              NULL, NULL, wc.hInstance, NULL );

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Create the vertex buffer
        if( SUCCEEDED( InitVB() ) )
        {
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // Enter the message loop
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
				} else {
                    Render();
				}
            }
        }
    }

    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

[Edited by - geniys on December 29, 2009 8:26:53 PM]
Advertisement
You can see that some vertices are out of their original positions.
If the tutorial is so bad, leave it. There's no point in trying to get a bad tutorial to work.
So maybe you could try directxtutorial.com.
Quote:Original post by snake5
You can see that some vertices are out of their original positions.
If the tutorial is so bad, leave it. There's no point in trying to get a bad tutorial to work.
So maybe you could try directxtutorial.com.


Wrong vertex position?
I can't understand fully. Some more information.
First: please use [ source] [ /source] tags. See the FAQ.

The rendering process appears okay from the image you posted. It's more likely that the vertex data you're using is incorrect.

Try a simpler shape, perhaps just 2 or 3 triangles, until you're confident you understand the process.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Try using a model loader for more complex shapes, hard-coding all this vertex-date is a pain...
I got it.

This behavior influenced with near plane, far plane value.

That values defined in view coordinate.

This topic is closed to new replies.

Advertisement