xbdev - software development
Sunday March 26, 2023
home | about | contact | Donations

PrtX. Rendering Image Directly to DirectX Screen Surface

by bkenwright@xbdev..net

* Download Full Source Code *

Sometimes all you want to do is put a simple image file directly to the screen.  It doesn't have to be as hard as all that....you can grabe the directx surface directly, load our image in and just copy it directly onto the surface....its just like that.  Using a couple of DirectX API's such as CopyRects, and LoadImageToSurface(..)

The program isn't much to look at but its very simple and you should easily understand.  The main part of the code thats new and exciting is in the function Render().  Most of the rest of it is the windows and directx setupcode.  But I've shown it all here so you can see it all


/*                                                                                */

/* File:   main.cpp                                                               */

/* Author: bkenwright@xbdev.net                                                   */

/* web:    www.xbdev.net                                                          */

/*                                                                                */



   Simple demo code that will load an image from a file and render it directly

   to our directx surface.  Simple and easy to use.






#include <windows.h>


#pragma comment(lib, "D3d8.lib")  // DirectX 8 library's

#pragma comment(lib, "D3dx8.lib")

#include <d3dx8.h>                // DirectX header files


#include <D3dx8tex.h> //  D3DXLoadSurfaceFromFile

// These are our DirectX3D global variables.

LPDIRECT3D8             g_pD3D           = NULL; // Used to create the D3DDevice

LPDIRECT3DDEVICE8       g_pd3dDevice     = NULL; // Our rendering device





//                                                                                //

// This little function is called over and over again, it has a simple mission in //

// this demo - its mission is to get us the back buffer surface, which we'll      //

// render on directly!  Yup directly...like in the old days of dos...heheh        //

//                                                                                //



void Render()




      IDirect3DSurface8 * pBackBuffer;

      g_pd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);

      //Get width and height of our screen surface



      int w=Desc.Width;    int h=Desc.Height;


      // Create a surface and load our image from a file onto it

      IDirect3DSurface8* pSurface;

      g_pd3dDevice->CreateImageSurface(w,h,D3DFMT_X8R8G8B8 , &pSurface);


      // File Name -------------------------------------+

      //                                                |

      //                                               \|/

      //                                                |

      D3DXLoadSurfaceFromFile(pSurface, NULL, NULL, "image.jpg" ,NULL, D3DX_DEFAULT,0, NULL) ;

      g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xFF0000FF, 0, 0);


    g_pd3dDevice->CopyRects(pSurface, NULL, 0, pBackBuffer , NULL );


    g_pd3dDevice->Present(NULL, NULL, NULL, NULL);





}//End Render()



//                                                                                \\

//  InitD3D is called once at the start of our program, and CleanUpDX is called   \\

//  once at the end of the program before closing.                                \\

//                                                                                \\



// Delete any allocated memory etc here.

void DXCleanup()


      // Release DirectX3D resources.



}//End DXCleanup(..)


// Initializes Direct3DX at the start.

bool DXInit(HWND hwnd)


    g_pD3D = Direct3DCreate8( D3D_SDK_VERSION );

      D3DDISPLAYMODE d3ddm;

    g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );


      int iWidth  = 640; // Simply set to zero for windowed!..NULL...nothing...you get the idea :)

      int iHeight = 480;


      D3DPRESENT_PARAMETERS d3dpp={iWidth,iHeight, d3ddm.Format, 1, (D3DMULTISAMPLE_TYPE)0,

                                    D3DSWAPEFFECT_DISCARD, NULL, true, TRUE, D3DFMT_D16, D3DPRESENTFLAG_LOCKABLE_BACKBUFFER, 0,0 };



    HRESULT e = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,

                                    D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice );


      if( e != D3D_OK )

            return false;


      //D3D_OK = S_OK = 0;

    return true;

}//End DXInit(..)








//                                                                                \\

//  Our Windows Code....this is the windows code...I cramed it together so that   \\

//  it has its bare essentials...couldn't get it any smaller than this...so that  \\

//  we could concentrate at the heart of our coding....Octee and not the windows  \\

//  code.                                                                         \\

//                                                                                \\





      switch( msg )


                  case WM_DESTROY:

            PostQuitMessage( 0 );

            return 0;



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

}//End MsgProc(..)





    // Register the window class

      char szName[] = "www.xbdev.net";

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,

                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,

                      szName, NULL };


    RegisterClassEx( &wc );


      HWND hWnd;


      // Create the application's window

      hWnd=CreateWindow( szName, szName,

                              WS_OVERLAPPEDWINDOW, 100, 100,

                                            8+640, 27+480, // The reason that we have these extra values

                                                           // for the width and height is because of the windows

                                                                   // border!  As the client rect is now 480x640, but we

                                                                   // have a caption bar etc...which is the extra size.

                              GetDesktopWindow(), NULL, wc.hInstance, NULL );


    // Initialize Direct3DX

    bool e = DXInit( hWnd );

      if( e==false )

            return 0;


      // 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 );






    // Clean up everything and exit the app


    UnregisterClass( szName, wc.hInstance );

    return 0;

}//End WinMain(..)


Well its not the greatest piece of code!  But its simple and you should be able to follow what is happening easily... my mission is accomplished :)

Might be worth noting, that you can also edit and manipulate the pixels directly on our screen surface...as we are grabbing the directx surface, its quiet simple to lock it and edit the pixels on the surface, creating effects such as fire, blur, stars etc...without ever loading a texture or doing any 3d work.  Sort of going back to the days of DirectDraw(..).



Copyright (c) 2002-2023 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.