Thread: 3 DirectX questions

  1. #1
    Slave MadCow257's Avatar
    Join Date
    Jan 2005
    Posts
    735

    3 DirectX questions

    1) I might make my terrain in my game as described in http://cprogramming.com/discussionar...eneration.html and I was wondering how you would get the pixel value of a point (i, j) on a surface using DirectX.

    2) When I have AIM running along with my full screen game and someone logs on or off, a flashing window pops up in the bottom right hand corner of my screen saying who logged on/off. Can I make it so AIM doesn't have the ability to write to the screen while my game's running? Even commercial games don't do this though so I'm thinking it might not be possible.

    3) When I return to my game after alt-tabbing out of it, the screen is just a gray screen. How do I fix this?

    Thanks for any help,
    MadCow
    Last edited by MadCow257; 03-07-2005 at 12:27 PM.

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    3) When I return to my game after alt-tabbing out of it, the screen is just a gray screen. How do I fix this?
    Your device is lost and you need to reset it.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Slave MadCow257's Avatar
    Join Date
    Jan 2005
    Posts
    735
    Alright, now I have this in render
    Code:
    	r = g_pDevice->TestCooperativeLevel();
    	if (r == D3DERR_DEVICELOST)
    		return E_FAIL;
    	if (r == D3DERR_DEVICENOTRESET)
    	{
    		pBackSurf->Release();
    		g_pDevice->Reset( &g_SavedPresParams );
    		if ( FAILED( r ) )
    		{
    			SetError("Could not reset device" );
    			PostQuitMessage( E_FAIL );
    			return E_FAIL;
    		}
    		r = g_pDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackSurf);
    		if ( FAILED( r ) )
    		{
    			SetError("Unable to reacquire back buffer" );
    			PostQuitMessage( 0 );
    			return E_FAIL;
    		}
    		g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 0.0f, 0 );
    	}
    However, now when I return from alt-tab the window just gets killed.

  4. #4
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    Quote Originally Posted by MadCow257
    1) I'm might my terrain in my game as described in http://cprogramming.com/discussionar...eneration.html and I was wondering how you would get the pixel value of a point (i, j) on a surface using DirectX.
    Im not reallly familiar with DX but since i wrote article i feel compeled to try and help

    You essentially need to load the image and access the raw pixel data. Here's a link that describes how to use the DX surfaces..
    http://msdn.microsoft.com/workshop/b...dxsurfaces.asp

    and heres an link that explains how to read the samples from the surface.
    http://msdn.microsoft.com/workshop/b...rgbreadptr.asp


    I dont know if this is the proper (and or best) way to go about this as DX is not something i use. However, after a bit of googling this all seems overly complicated
    My advice is to write a simple image loader for an uncompressed file format (.bmp, .ppm, .tga, etc...) and then you'll have straight access to the pixel data by whatever means you choose to store it.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You need to lock the surface and then compute the offset into the surface or array.

    DWORD offset=(y*Surface.MemPitch)+x;

    DWORD value=Surface.lpBits[offset];

    But to do this you must specify to DirectX that you want a backbuffer that is lockable. Otherwise this code will do nothing.

    I will show you with my old Voxel terrain code.

    This is a class that encapsulates some aspects of a very simple DirectX back buffer surface.

    Code:
    #ifndef BACKBUFFER
    #define BACKBUFFER
    #include <d3dx9.h>
    #include "D3DError.h"
    
    
    class CBackBuffer
    {
      protected:
        IDirect3DDevice9        *Device;
        IDirect3DSwapChain9     *SwapChain;
        IDirect3DSurface9       *Surface;
        D3DSURFACE_DESC         BufferDesc;
        D3DLOCKED_RECT          BLRect;
    
        void                   *Buffer;
        int                     MemPitch;
        
      public:
        CBackBuffer(IDirect3DDevice9 *device);
        
        int Pitch(void) {return MemPitch;};
        int Width(void) {return BufferDesc.Width;};
        int Height(void) {return BufferDesc.Height;};
    
        void *Lock(void);
        HRESULT Unlock();
    
    
    };
    
    #endif
    Code:
    #include "CBackBuffer.h"
    #include <stdio.h>
    
    
    CBackBuffer::CBackBuffer(IDirect3DDevice9 *device)
    {
      Device=device;
      
      Device->GetSwapChain(0,&SwapChain);
      SwapChain->GetBackBuffer(D3DADAPTER_DEFAULT,D3DBACKBUFFER_TYPE_MONO,&Surface);
    
      if (!Surface) ::MessageBox(0,"GetBackBuffer Failed",0,0);
    
      
      if FAILED(Surface->GetDesc(&BufferDesc)) ::MessageBox(0,"GetDesc Failed",0,0);
    
      
    }
    
    void *CBackBuffer::Lock(void)
    {
      D3DLOCKED_RECT lrect;
      HRESULT hr;
      hr=Surface->LockRect(&lrect,0,0);
      if FAILED(hr)
      { 
        
        char *text=D3DError::GetTextFromD3DError(hr);
    
        ::MessageBox(0,text,0,0);
        return NULL;
      }
     
      
      MemPitch=lrect.Pitch>>2;
      
      return  lrect.pBits;
    
    }
    
    HRESULT CBackBuffer::Unlock(void)
    {
      HRESULT hr=Surface->UnlockRect();
      return hr;
    }
    With this code you should be able to lock the surface and then write to or read from it.

    But you don't need to do this to accomplish what that article is talking about.

    To ease pain and suffering on your part, I would load the textures into memory using arrays. Then based on the height value, instead of choosing a color, choose an array to extract the actual texel RGBs from. So for a terrain with 6 different textures for heights, you would have 6 different arrays. After you create the final image, you can safely delete the 6 arrays because you don't need them anymore.

    Now when you texture your quads you simply iterate through your terrain grid and set each vertex's u,v to correctly index into the texture you just created. The downside to this is that your terrain grid must be the same exact size as your texture size.

    I would start by at least getting a flat grid of triangulated quads up and running. Then create simple terrain by displacing the Y component of each vertex either positively or negatively. Once you begin to see how this affects your overall terrain, then just load a greyscale bitmap into memory. All white is high, all black is low. Low means max positive displacement and high means max negative displacement. Iterate through the heightmap and extract the value from the array or heightmap. Set the current vertex Y to correspond with the grey scale color in the image.
    It could be as simple as:

    Code:
    ...
    float fRatio=(float)HeightMap[offset]/(float)ucharMaxHeight;
    float fHeight=255.0f*fRatio;
    
    Vertex[vertexnum].x=XCoord;
    Vertex[vertexnum].y=fHeight;
    Vertex[vertexnum].z=ZCoord;
    
    ...

    If you need more help, let me know and I'll explain further.
    Last edited by VirtualAce; 03-07-2005 at 01:58 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Directx questions
    By lruc in forum Game Programming
    Replies: 8
    Last Post: 07-07-2011, 10:26 PM
  2. 2 questions in DirectX
    By X PaYnE X in forum Game Programming
    Replies: 4
    Last Post: 12-02-2004, 09:38 AM
  3. A Few questions, DirectX
    By St0rmTroop3er in forum Game Programming
    Replies: 1
    Last Post: 09-26-2003, 06:28 PM
  4. newb-ish DirectX questions
    By confuted in forum Game Programming
    Replies: 4
    Last Post: 07-06-2003, 08:14 AM
  5. Various DirectX questions
    By Hunter2 in forum Game Programming
    Replies: 6
    Last Post: 11-28-2002, 09:42 PM