Skip to main content
gamedev.net
🔒 Locked

Coordinates

Started by stece Jan 17, 2008 at 1:36 PM 6 replies 1k views
Original Post
stece
stece
Dear all I know the screen coordinates only, which as far as I know are transformed coordinates (x,y,z). In SDK samples, there are untransformed coordinates ( like 1.0f, 1.0f, 1.0f) used. I don't understand how to plan a picture using these coordinates. I was searching DirectX help to find something more how to use these coordinates, but I didn't find anything. Could somebody hint me at how to use them or where I can read about it? Which coordinates are used to plan games scenarios? Could I know transformed screen coordinates only and be with it? ( I think no) Thank you in advance.
TiPiou
TiPiou
if you want to display 2D things with DirectDraw (not advised, as DirectDraw was dropped with DirectX8 I guess) you only need screen coordinates.

if you want to display 2D things with Direct3D, you use either textured quads or sprites, and if you wish, you can use already transformed coordinates (i.e. screen coordinates, as you stated) and be happy with it

if you want to display anything 3D, then you need to provide untransformed coordinates. They represent the position of your objects in you "world", and the screen coordinates have a meaning only if you describe from where you are watching this world, using transformation matrixes (you need at least a View, and a Projection). Useful info about 3D transformations is easily accessible in the "Getting Started" section in the "Programming Guide" chapter of Direct3D documentation.

regards,
- TiPiou -
Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/
stece
stece
I wrote a code like this:

#include <Windows.h>#include <mmsystem.h>#include <d3dx9.h>#pragma warning( disable : 4996 ) // disable deprecated warning #include <strsafe.h>#pragma warning( default : 4996 ) //-----------------------------------------------------------------------------// Global variables//-----------------------------------------------------------------------------LPDIRECT3D9             g_pD3D       = NULL; // Used to create the D3DDeviceLPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering deviceLPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL; // Buffer to hold vertices//LPDIRECT3DTEXTURE9      g_pTexture   = NULL; // Our texture// A structure for our custom vertex type. We added texture coordinatesstruct CUSTOMVERTEX{    D3DXVECTOR3 position; // The position    D3DCOLOR    color;    // The color    //FLOAT       tu, tv;   // The texture coordinates};// Our custom FVF, which describes our custom vertex structure#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)//|D3DFVF_TEX1)//-----------------------------------------------------------------------------// Name: InitD3D()// Desc: Initializes Direct3D//-----------------------------------------------------------------------------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.BackBufferFormat = D3DFMT_UNKNOWN;    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    // Turn off culling    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );    // Turn off D3D lighting    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );    // Turn on the zbuffer    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );    return S_OK;}HRESULT InitGeometry(){    // Use D3DX to create a texture from a file based image   /* if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"banana.bmp", &g_pTexture ) ) )    {         If texture is not in current folder, try parent folder        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"..\\banana.bmp", &g_pTexture ) ) )        {            MessageBox(NULL, L"Could not find banana.bmp", L"Textures.exe", MB_OK);            return E_FAIL;        }    }*/D3DXVECTOR3 vect[]= {	D3DXVECTOR3( 0.5f, 0.0f, 0.0f ),	D3DXVECTOR3( 0.5f, 0.5f, 0.0f ),	D3DXVECTOR3( 0.0f, 0.5f, 0.0f ),	D3DXVECTOR3( 0.5f, 0.0f, 0.0f )	};    // Create the vertex buffer.    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),                                                  0, D3DFVF_CUSTOMVERTEX,                                                  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )    {        return E_FAIL;    }    // Fill the vertex buffer. We are setting the tu and tv texture    // coordinates, which range from 0.0 to 1.0    CUSTOMVERTEX* pVertices;    if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )        return E_FAIL;    for( DWORD i=0; i<3; i++ )    {                pVertices.position = vect;        pVertices.color    = 0xffffffff;        //pVertices.tu       = 0.0f;        //pVertices.tv       = 1.0f;	}    g_pVB->Unlock();    return S_OK;}//-----------------------------------------------------------------------------// Name: Cleanup()// Desc: Releases all previously initialized objects//-----------------------------------------------------------------------------VOID Cleanup(){    //if( g_pTexture != NULL )     //   g_pTexture->Release();    if( g_pVB != NULL )        g_pVB->Release();    if( g_pd3dDevice != NULL )        g_pd3dDevice->Release();    if( g_pD3D != NULL )        g_pD3D->Release();}//-----------------------------------------------------------------------------// Name: Render()// Desc: Draws the scene//-----------------------------------------------------------------------------VOID Render(){	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 our texture. Using textures introduces the texture stage states,        // which govern how textures get blended together (in the case of multiple        // textures) and lighting information. In this case, we are modulating        // (blending) our texture with the diffuse color of the vertices.       /* g_pd3dDevice->SetTexture( 0, g_pTexture );        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );*/        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );        // End the scene        g_pd3dDevice->EndScene();    }    // Present the backbuffer contents to the display    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );}//-----------------------------------------------------------------------------// Name: MsgProc()// Desc: The window's message handler//-----------------------------------------------------------------------------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 );}//-----------------------------------------------------------------------------// Name: wWinMain()// Desc: The application's entry point//-----------------------------------------------------------------------------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, 0, 0, 1000, 780,                              NULL, NULL, wc.hInstance, NULL );    // Initialize Direct3D    if( SUCCEEDED( InitD3D( hWnd ) ) )    {        // Create the vertex buffer        if( SUCCEEDED( InitGeometry()  ) )        {            // 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;}


I don't understand why the created triangle looks like this ( has its size and location)?
Could somebody tell me what mean these coordinates I created. I made them by accident and I got a triange, but I don't understand how it works?
The thing about transformation I read from SDK help but I can't calculate screen coordinates onto untransformed coordinates.
If somebody could help I'd appreciate it.
Thank you in advance.
TiPiou
TiPiou
Well, you got a triangle because you initialized four coordinates, then you created a vertex buffer with enough room for three of your vertices, you copied the first three of your four coordinates in this vertex buffer, and then asked with this line :
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );
to draw one element of a triangle strip with those, i.e, a triangle (3 vertices)
but I guess you already figured that out ;)

Now : first, you did not set a world, neither a view, neither a projection matrixes.
(those things are done with
IDirect3DDevice9::SetTransform(D3DTS_WORLDMATRIX, &yourWorldMatrix)
IDirect3DDevice9::SetTransform(D3DTS_VIEW, &yourViewMatrix)
IDirect3DDevice9::SetTransform(D3DTS_PROJECTION, &yourProjectionMatrix)
and D3DX provides handy ways of initializing them with functions like
D3DXMatrixIdentity(), D3DXMatrixLookatLH() and D3DXMatrixPerspectiveFovLH())

Since you did not call SetTransform, those matrixes are not guaranteed to be initialized at all, so the results are unpredictable, but with some luck they were silently initialized with identity matrixes for the three of them, meaning your untransformed vertices (0.5f,0.0f,0.0f), (0.5f,0.5f,0.0f) and (0.0f,0.5f,0.0f) forming your triangle results in the exact same vertices when transformed.

If so, it would be as if you used already transformed vertices coordinates.
The proper way to use transformed texture coordinates as it seems you want to, is to write this line :
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
instead of the one you wrote
Notice the D3DFVF_XYZRHW flag, different from the D3DFVF_XYZ flag you used. This tells Direct3D that the values of the vertices' positions you provide are already transformed. You then are sure that your vertices won't get transformed by uninitialized matrixes, and you don't bother with matrix transformations at all.

Now, I'm afraid I can't help much more with why you got this or that, since I don't know what your results looked like... moreover, I don't recall how transformed coordinates have to be passed to the rasterizer. My guess is that it won't be integer pixel counts (maybe like those you already worked with). I think the coordinates in which you have to describe your vertices are in such a referential where (X,Y) = (0.0f,0.0f) is likely to be the center of the viewport (i.e your window), (-1.0f,-1.0f) may very well be the top-left corner of the window, and (1.0f,1.0f) the bottom-right one. Maybe I'm making a mistake and (-0.5f,-0.5f) would be top-left and (0.5f,0.5f) bottom-right. Maybe I'm making another mistake and what I think to be the top is in fact the bottom.

do you have any screenshot of your results ? I could maybe check this with you ;)

[edit] maybe I'm totally wrong and you can work with per-pixel coordinates, as values used in tutorial02 show. Also, with the D3DFVF_XYZRHW flag, your position need a fourth component (use a D3DXVECTOR4) which you can set to 1.0f for every vertex.

[Edited by - TiPiou on January 17, 2008 4:30:47 PM]
Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/
stece
stece
When I use coordinates like this:
D3DXVECTOR3 vect[]= {
D3DXVECTOR3( 0.5f, 0.0f, 0.0f ),
D3DXVECTOR3( 0.5f, 0.5f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.5f, 0.0f ),
D3DXVECTOR3( 0.5f, 0.0f, 0.0f )
};
My triangle is smaller and located closer to the center.


When coordinates are like this :
D3DXVECTOR3 vect[]= {
D3DXVECTOR3( 0.7f, 0.0f, 0.0f ),
D3DXVECTOR3( 0.7f, 0.7f, 0.0f ),
D3DXVECTOR3( 0.0f, 0.7f, 0.0f ),
D3DXVECTOR3( 0.7f, 0.0f, 0.0f )
};
So my triangle gets bigger and moves towards top right corner. Why?
How do these coordinates work?
Sorry but I don't know how to paste my screenshot here. I tried hosting it at ImageShack and the exchanging it as a file but I got server error.
Evil Steve
Evil Steve
Well, you're specifying points in 3D space, so the position of the triangle depends on the position of those points and the position of your "camera". The camera is defined using the view and projection matrices, and you can additionally transform everything in your scene with a world matrix.
From the looks of your code, you're not setting any matrices, so I'm surprised you can see anything (They'll all default to an identity matrix). You'll almost certainly want to at least set a projection and view matrix with something like the following code:
D3DXMATRIX matView, matProj;D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1000.0f/780.0f, 0.1f, 1000.0f);D3DXVECTOR3 vEye(0, 0, -5);D3DXVECTOR3 vAt(0, 0, 1);D3DXVECTOR3 vUp(0, 1, 0);D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp);g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

That creates a camera with a 60 degree FOV, an aspect ratio of 1000/780 = ~1.28, with the camera at (0, 0, -5), looking at (0, 0, 1), with Y being "Up".

Quote:
Original post by stece
Sorry but I don't know how to paste my screenshot here. I tried hosting it at ImageShack and the exchanging it as a file but I got server error.
You should be able to upload the image somewhere (Imageshack is fine), then link to it with HTML like so:
&ltimg src="http://foo.com/blah/myimage.jpg">
stece
stece
Quote:

so the position of the triangle depends on the position of those points


This is my whole thread about. I understand matricies and "cameras", but I don't undestand how to plan the positioning in untransformed coordinates.
What is a position of a point ( 0.5f, 0.0f, 0.0f )?
If there is Cartesian x,y,z this is simple to me, but I don't know how to manage those 0.5f for example. What it means de facto?
Can a coordinate be fractional and if so, what it means?
I intentionally removed matricies from my code to focus on those magical coordinates.

Thank you in advance

I've been working on this and seem to have comprehended. It's all relative and a little hard to get, but thanks for your explainations.


[Edited by - stece on January 18, 2008 8:21:14 AM]
TiPiou
TiPiou
Quote:
Original post by stece
If there is Cartesian x,y,z this is simple to me, but I don't know how to manage those 0.5f for example. What it means de facto?

oh, that IS your question, then ^^ well, those are entirely cartesian coordinates, and 0.5f means it is a floating point value (some kind of Real number, with decimals) of 0.5, meaning 1/2.
0.25f = 1/4
etc. :p


Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.