Thread: DirectX | Simple Drawing

  1. #1
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265

    DirectX | Simple Drawing

    How do I draw a single pixel?
    How do I draw a text?
    and yes, I have tried to look for the answer before comming here.

    Thanks [=
    gavra.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by gavra View Post
    How do I draw a single pixel?
    Google "directX points".
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    I have tried this too.
    gavra.

  4. #4
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    I don't wanna hijack this thread, but this question made me wonder, if you are writing a directX application, and you want to adjust the pixel colour of a single pixel, could you not just use the windows api function SetPixel()? Would that technique work in a directX application? Which method is better to use?

    I can imagine that this technique probably doesn't work, and even if it did, probably wouldn't be the best way of doing it because you're mixing two APIs unnecessarily.

  5. #5
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    I think it's possible but when I tried to do that it didn't work very well.

    Anyway, I succeed to work something out by using LPD3DXLINE.
    In the tutorial I'm using it has been said that the render function should be in an "infinite" loop (until we recognaize that the 'escape' key was pressed) but, it's slowing the part of recognazing the message (I'm using PeekMessage).
    I'm sure it's not suposed to be this way.
    Any explanation?
    gavra.

  6. #6
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Can you post the code? It's slowing down? Basically you check to see if you have a message in the queue, if so you process it, if not you call your render function. You do this over and over until you get a keyboard message with escape pressed. Theres also a million examples of writing the game loop, check out http://www.directxtutorial.com/.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    This should draw a point field centered around 0,0,0 in local space.
    Set the projection matrix to FOV 60, z-near 1.0f, z-far 1100.0f.
    Set the view matrix to identity or do a look at left handed matrix that is looking at 0.0f,0.0f,0.0f (use D3DXMatrixLookAtLH()) or looking at wherever you translate the point field to in world space.
    Clear the device and call SimpleDrawing::Render().

    I have not compiled this and wrote it from scratch so there might be some compiler errors.
    Your render loop might be something like this:
    Code:
    ...
    m_pSceneGraph->Render(m_pDevice);
    m_pSceneGraph->Update(timeDelta);
    ...
    Your scene graph render might look like:

    Code:
    ...
    for (size_t i = 0;i < m_RenderObjects.size(); ++i)
    {
       m_RenderObjects[i]->Render(pDevice);
    }
    ...
    Your update might look like:
    Code:
    ...
    m_pInputHandler->Update(timeDelta);
    ...
    Simple Drawing object - point field
    Code:
    struct SimpleVertex
    {
       D3DXVECTOR3 vecPos;
       D3DCOLOR color;
    
       static const DWORD FVF() { return D3DFVF_XYZ | D3DFVF_DIFFUSE; }
    
       SimpleVertex() : vecPos(0.0f,0.0f,0.0f), color(0)
       {
       }
    
       SimpleVertex(float x,float y,float z,D3DCOLOR color) : vecPos(x,y,z),color(color)
       {
       }
    };
    
    class SimpleDrawing
    {
       public:
         SimpleDrawing();
         virtual ~SimpleDrawing();
    
         void Create(unsigned int numVertices);
         void Render(IDirect3DDevice9 *pDevice);
         void Update(float timeDelta); 
    
       private:
         SimpleVertex *m_pVerts;
         unsigned int m_numVertices;
    
         float GetRandomFloatInRange(float min,float max);
    };
    
    ...
    
    SimpleDrawing::SimpleDrawing() : m_pVerts(0)
    , m_numVertices(0)
    {
    }
    
    SimpleDrawing::~SimpleDrawing()
    {
       if (m_pVerts)
       {
          delete [] m_pVerts;
          m_pVerts = 0;
       }
    }
    
    void SimpleDrawing::Create(unsigned int numVertices)
    {
       m_numVertices = numVertices;
    
       //Allocate user vertex buffer
       try
       {
          m_pVerts = new SimpleVertex[numVertices];
       }
       catch (std::bad_alloc &ba)
       {
           ba;
           return;
       }
    
       //Create vertices
       for (unsigned int i = 0;i < numVertices; ++i)
       {
           float x = GetRandomFloatInRange(-1000.0f,1000.0f);
           float y = GetRandomFloatInRange(-1000.0f,1000.0f);
           float z = GetRandomFloatInRange(-1000.0f,1000.0f);
           
           m_pVerts[i] = SimpleVertex(x,y,z,D3DXCOLOR(1.0f,1.0f,1.0f,1.0f));
        }
    }
    
    void SimpleDrawing::Update(float timeDelta)
    {
    }
    
    void SimpleDrawing::Render(IDirect3DDevice9 *pDevice)
    {
       //Set world matrix to identity
       D3DXMATRIX matIdent;
       D3DXMatrixIdentity(&matIdent);
       pDevice->SetTransform(D3DTS_WORLD,&matIdent);
    
       //Draw points
       pDevice->SetFVF(SimpleVertex::FVF);
       pDevice->DrawPrimitiveUP(D3DPT_POINTLIST,m_numVertices,m_pVerts,sizeof(SimpleVertex));
    }
    
    float SimpleDrawing::GetRandomFloatInRange(float min,float max)
    {
       unsigned int value = rand() % 1000;
       float lerpFactor = static_cast<float>(value) / 1000.0f;
       return min + lerpFactor * (max - min);
    }
    Do not mix GDI and Direct3D. GDI is not performance-based and Direct3D is. They do not play with each other very well. For input you can use DirectInput or the Windows message loop.
    Last edited by VirtualAce; 05-28-2009 at 06:53 PM.

  8. #8
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    Thank's Valaris, this is the tutorial that i'm using [=
    Heres the code:
    Code:
    #include <windows.h>
    #include <windowsx.h>
    #include <d3d9.h>
    #include <D3dx9core.h>
    
    #pragma comment(lib, "d3d9.lib")
    #pragma comment(lib, "D3dx9.lib")
    
    #define SCREEN_WIDTH  1280
    #define SCREEN_HEIGHT 1024
    #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) 
    
    // global declarations
    LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface
    LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class
    
    const double PI = 3.14159265358979323846264338327950288419;
    
    // function prototypes
    void initD3D(HWND hWnd);    // sets up and initializes Direct3D
    void RenderFrame(void);    // renders a single frame
    void cleanD3D(void);    // closes Direct3D and releases memory
    void SetBackgroundColor(int r, int g, int b);
    void DrawPoint(float x, float y, DWORD color);
    void DrawLine(float x1, float y1, float x2, float y2, DWORD color);
    void DrawCircle(float x, float y, float radius, DWORD color);
    
    // the handle for the window, filled by a function
    HWND hWnd;
    
    // the WindowProc function prototype
    LRESULT CALLBACK WindowProc(HWND hWnd,
                             UINT message,
                             WPARAM wParam,
                             LPARAM lParam);
    
    // the entry point for any Windows program
    int WINAPI WinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nCmdShow)
    {
    
        // this struct holds information for the window class
        WNDCLASSEX wc;
    
        // clear out the window class for use
        ZeroMemory(&wc, sizeof(WNDCLASSEX));
    
        // fill in the struct with the needed information
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WindowProc;
        wc.hInstance = hInstance;
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wc.lpszClassName = "WindowClass1";
    
        // register the window class
        RegisterClassEx(&wc);
    
        // create the window and use the result as the handle
        hWnd = CreateWindowEx(NULL,
                              "WindowClass1",    // name of the window class
                              "Direct3D",   // title of the window
                              WS_EX_TOPMOST | WS_POPUP, // WS_OVERLAPPEDWINDOW for windowed mode // window style
                              0,    // x-position of the window
                              0,    // y-position of the window
                              SCREEN_WIDTH,    // width of the window
                              SCREEN_HEIGHT,    // height of the window
                              NULL,    // we have no parent window, NULL
                              NULL,    // we aren't using menus, NULL
                              hInstance,    // application handle
                              NULL);    // used with multiple windows, NULL
    
        // display the window on the screen
        ShowWindow(hWnd, nCmdShow);
    
        // set up and initialize Direct3D
        initD3D(hWnd);
    
        // enter the main loop:
    
        MSG msg;
        				RenderFrame();
    	while(TRUE)
        {
            while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
    
    
    		if(msg.message == WM_QUIT)
                break;
    
    		if(KEY_DOWN(VK_ESCAPE))
    			PostMessage(hWnd, WM_DESTROY, 0, 0); 
        
    	}
    
        // clean up DirectX and COM
        cleanD3D();
    
        return msg.wParam;
    }
    
    // this is the main message handler for the program
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        // sort through and find what code to run for the message given
        switch(message)
        {
            // this message is read when the window is closed
            case WM_DESTROY:
                {
                    // close the application entirely
                    PostQuitMessage(0);
                    return 0;
                } break;
        }
    
        // Handle any messages the switch statement didn't
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
    
    // this function initializes and prepares Direct3D for use
    void initD3D(HWND hWnd)
    {
        d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface
    
        D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information
    
        ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use
        d3dpp.Windowed = FALSE;    // TRUE = WINDOWED
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames
        d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D
    	// for Full Screen Mode
    	d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;    // set the back buffer format to 32-bit
    	d3dpp.BackBufferWidth = SCREEN_WIDTH;    // set the width of the buffer
        d3dpp.BackBufferHeight = SCREEN_HEIGHT;    // set the height of the buffer
    
        // create a device class using this information and information from the d3dpp stuct
        d3d->CreateDevice(D3DADAPTER_DEFAULT,
                          D3DDEVTYPE_HAL,
                          hWnd,
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          &d3dpp,
                          &d3ddev);
    }
    
    // this is the function used to render a single frame
    void RenderFrame(void)
    {
        // clear the window to a deep blue
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
    
        d3ddev->BeginScene();    // begins the 3D scene
    
        // do 3D rendering on the back buffer here
    	DrawLine(0,0,SCREEN_WIDTH,0,0xffffffff);
    	DrawLine(0,0,0,SCREEN_HEIGHT,0xffffffff);
    	DrawLine(0,SCREEN_HEIGHT-1,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0xffffffff);
    	DrawLine(SCREEN_WIDTH-1,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0xffffffff);
    
        d3ddev->EndScene();    // ends the 3D scene
    
        d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame
    }
    
    // this is the function that cleans up Direct3D and COM
    void cleanD3D(void)
    {
        d3ddev->Release();    // close and release the 3D device
        d3d->Release();    // close and release Direct3D
    }
    
    void SetBackgroundColor(int r, int g, int b)
    {
        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(r, g, b), 1.0f, 0);
        d3ddev->Present(NULL, NULL, NULL, NULL);    // displays the created frame
    }
    
    void DrawLine(float x1, float y1, float x2, float y2, DWORD color)
    {
    		LPD3DXLINE line;
            D3DXCreateLine(d3ddev, &line);
            D3DXVECTOR2 lines[] = {D3DXVECTOR2(x1, y1), D3DXVECTOR2(x2, y2)};
            line->Begin();
            line->Draw(lines, 2, color);
            line->End();
            line->Release();
    }
    
    void DrawPoint(float x, float y, DWORD color)
    {
    	DrawLine(x, y, x + 1, y + 1, color);
    }
    
    void DrawCircle(float x, float y, float radius, DWORD color)
    {
         double t;
         for (t = 0.000;t <= PI*2;t += 0.001)
             DrawPoint((float)(radius*cos(t) + x), (float)(radius*sin(t) + y), color);
    }
    Don't pay attention to the remarks (most of the code was taken from the tutorial).
    I assume that I didn't write my functions right.

    Thank's Bubba, I would be happy if you could have a look on my code (:

    and by the way, is there any written codes to make all of this easier for me?
    gavra.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    and by the way, is there any written codes to make all of this easier for me?
    Indeed there is and most of the regulars on this board have code that would help. However it is not something that can be explained in one post or a thousand posts. Because of that I highly recommend buying books from amazon. It really is the only way you are going to get a fair treatment of the subject matter. And don't stop with just one book. Just as in any field the more books you read the better overall picture you get.

    Tutorials on the internet are very good but they will leave you wanting more. Few of them dive into the nitty gritty details about how to put said tutorial into a system and most tutorials are so geared to teach one topic that often the code cannot be ported to work inside of a system.
    But it is the nitty gritty details that will make or break your system so while tutorials are great at focusing on one or two key concepts they lack the bigger picture. Admittedly you as a programmer should be able to plug the tutorials into the bigger picture since that is really your job but it's not always a simple task even when you know the subject matter.

    Read/research, code, read/research, code,...repeat about a hundred thousand times. Today's technologies will not be here tomorrow and unless you keep up with your reading and research you will get left behind. As far as graphics go it is how all of us learned what we know and it is how we will continue to learn new things and new APIs.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. DirectX screenshot via C (app crashes)
    By Delusionz in forum C Programming
    Replies: 6
    Last Post: 01-11-2009, 09:55 AM
  2. Simple Socialising Chat Bots
    By bengreenwood in forum C++ Programming
    Replies: 10
    Last Post: 11-28-2007, 08:42 AM
  3. Problems with my DirectX program
    By fighter92 in forum Game Programming
    Replies: 1
    Last Post: 01-23-2007, 06:28 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Simple program for drawing
    By kreyes in forum C Programming
    Replies: 1
    Last Post: 02-08-2002, 01:37 AM