After figuring out how to draw a sprite and examining the possible parameters for each function and some extensive googling I can't find out how to draw to the desktop, can someone point me in the right direction?
EDIT: Here is what I have tried already and what happened, I am using the following code as a learning point for my program:
// main.cpp : Defines the entry point for the application.
//
#include "C:\Program Files\Microsoft DirectX SDK (August 2008)\Include\D3dx9core.h"
#include "C:\Documents and Settings\Death\My Documents\Downloads\DXSprite\DXSprite\resource.h"
#include <windows.h>
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
HWND g_hWnd = NULL;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
ID3DXSprite * g_pD3DXSprite = NULL;
LPDIRECT3DTEXTURE9 g_pTexture = NULL;
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
//-----------------------------------------------------------------------------
// PROTOTYPES
//-----------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT InitializeD3D ( );
void RenderFrame ( );
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
WNDCLASSEX winClass;
MSG uMsg;
HRESULT hr;
memset(&uMsg,0,sizeof(uMsg));
winClass.lpszClassName = "MY_WINDOWS_CLASS";
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW;
winClass.lpfnWndProc = WindowProc;
winClass.hInstance = hInstance;
winClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDC_DXSPRITE);
winClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDC_DXSPRITE);
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
if( !RegisterClassEx(&winClass) )
return E_FAIL;
g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS",
"Direct3D 9 - ID3DXSprite Example",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL );
if( g_hWnd == NULL )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
UpdateWindow( g_hWnd );
//----------------------------------------------------------------
// Create the DirectX device
//----------------------------------------------------------------
if (FAILED( InitializeD3D()))
return 0;
//----------------------------------------------------------------
// CREATE THE ID3DXSprite
//----------------------------------------------------------------
// Create the ID3DXSprite interface object
hr = D3DXCreateSprite(g_pD3DDevice, &g_pD3DXSprite );
if( FAILED(hr) )
return hr;
//----------------------------------------------------------------
// LOAD THE TEXTURE FOR THE SPRITE
//----------------------------------------------------------------
// --------------------------------------------------------
// Load the texture. I decided to use the extended
// version of the texture loading function just to show what
// it would look like.
// The texture was created with Photoshop with a transparent
// background to start with. Then line cross hairs were added.
//
// Note - If you don't use a texture image that has a power of
// 2 size for the width or height then the image may not load
// properly. This image is 256x256.
//
D3DXCreateTextureFromFileEx(
g_pD3DDevice,
"C:\\Documents and Settings\\Death\\My Documents\\45handold2.tga", // Our texture image!
D3DX_DEFAULT, // width
D3DX_DEFAULT, // height
D3DX_DEFAULT, // MIP levels
0, // usage
D3DFMT_DXT1, // texture format
D3DPOOL_MANAGED, // mem pool
D3DX_DEFAULT, // filter
D3DX_DEFAULT, // MIP filter
0, // transparent color key
NULL, // image info struct
NULL, // palette
&g_pTexture); // the returned texture, if success
if ( FAILED(hr) )
return hr;
// ---------
// Main Loop
// ---------
while( uMsg.message != WM_QUIT )
{
if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
}
}
// -------------------------
// Release directx resources
// -------------------------
if (g_pD3DXSprite)
{
g_pD3DXSprite->Release();
g_pD3DXSprite = NULL;
}
if (g_pTexture)
{
g_pTexture->Release();
g_pTexture = NULL;
}
if (g_pD3DDevice)
{
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}
UnregisterClass( "MY_WINDOWS_CLASS", winClass.hInstance );
return (int)uMsg.wParam;
}
//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT CALLBACK WindowProc( HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam )
{
switch( msg )
{
case WM_KEYDOWN:
{
switch( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
}
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
default:
{
RenderFrame();
return DefWindowProc( hWnd, msg, wParam, lParam );
}
break;
}
return 0;
}
//-----------------------------------------------------------------------------
// Name: InitializeD3D()
// Desc: Create DirectX interface objects
// Initialize the view matrix.
// Setup render states that will not need changing throughout
// the life of the application.
//-----------------------------------------------------------------------------
HRESULT InitializeD3D( )
{
HRESULT hr;
// Create a direct 3D interface object
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if( g_pD3D == NULL )
{
// TO DO: Respond to failure of Direct3DCreate9
return E_FAIL;
}
D3DDISPLAYMODE d3ddm;
if( FAILED( hr = g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
{
// TO DO: Respond to failure of GetAdapterDisplayMode
return hr;
}
//
if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
if( hr == D3DERR_NOTAVAILABLE )
// POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
return hr;
}
//
// Do we support hardware vertex processing? If so, use it.
// If not, downgrade to software.
//
D3DCAPS9 d3dCaps;
if( FAILED( hr = g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, &d3dCaps ) ) )
{
// TO DO: Respond to failure of GetDeviceCaps
return hr;
}
DWORD dwBehaviorFlags = 0;
if( d3dCaps.VertexProcessingCaps != 0 )
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//
// Everything checks out - create a simple, windowed device.
//
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
// Attempt to create a HAL device, end app on failure just to keep things
// simple. In other words we are not trying to create a REF device if the
// HAL fails.
if( FAILED( hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
dwBehaviorFlags, &d3dpp, &g_pD3DDevice ) ) )
{
MessageBox (NULL,NULL,NULL,NULL);
}
// If we get here everything worked!
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RenderFrame()
// Desc: Draw the image to the framebuffer.
//-----------------------------------------------------------------------------
void RenderFrame( )
{
if (!g_pD3DDevice && !g_pD3DXSprite && !g_pTexture)
return;
// Clear the frame & depth buffer ready for drawing (Black color)
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
g_pD3DDevice->BeginScene();
{
//-------------------------
// Render the sprite
//
D3DXVECTOR3 vecPos = D3DXVECTOR3(0,0,0);
if (g_pD3DXSprite && g_pTexture)
{
g_pD3DXSprite->Begin( D3DXSPRITE_ALPHABLEND );
g_pD3DXSprite->Draw(g_pTexture, NULL, NULL, &vecPos, 0xffffffff);
g_pD3DXSprite->End();
}
}
g_pD3DDevice->EndScene();
// Frame buffer to Front buffer
g_pD3DDevice->Present( NULL, NULL, NULL, NULL );
}
I have tried changing the parameter g_hWnd in the CreateDevice method to HWND_DESKTOP, I figured it would work since you can draw directly to the desktop by drawing to HWND_DESKTOP in GDI, unfortunately this simply resulted in the CreateDevice method failing. I looked into the IDirect3D9 class methods for some way to make a device context with HWND_DESKTOP similar to GDI because I suspected that's how I should go about finding a way to draw to the desktop. No luck, I've of course done the obvious google search "how to draw to desktop DirectX"(and various other combinations of the same question) in hopes to find an answer but nothing seems to be turning up, the closest thing I've found is someone drawing a transparent window and drawing the desired contents on top of that window but I thought there's probably a more elegant solution.
Related
In the code below i wanted to display an image or some pixels by using surface and backbuffer.
It compiles correctly but gives a run-time error when reach to GetSurfaceLevel or LockRect.
The code:
#include <d3d9.h>
#include <windows.h>
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DSURFACE9 surf,back;
D3DLOCKED_RECT lock ;
IDirect3DTexture9* texture = NULL;
HRESULT InitD3D( HWND );
HRESULT InitVB();
VOID Cleanup();
VOID Render();
LRESULT WINAPI MsgProc( HWND , UINT , WPARAM , LPARAM );
//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
UNREFERENCED_PARAMETER( hInst );
// Register the window class
WNDCLASSEX wc =
{
sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL
};
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 02: Vertices",
WS_OVERLAPPEDWINDOW, 100, 100, 320, 240,
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 );
printf("4");
Render();
printf("5");
// 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 );
}
}
}
}
UnregisterClass( "D3D Tutorial", wc.hInstance );
return 0;
}
//-----------------------------------------------------------------------------
// 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.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd;
// 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
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitVB()
// Desc: Creates a vertex buffer and fills it with our vertices. The vertex
// buffer is basically just a chuck of memory that holds vertices. After
// creating it, we must Lock()/Unlock() it to fill it. For indices, D3D
// also uses index buffers. The special thing about vertex and index
// buffers is that they can be created in device memory, allowing some
// cards to process them in hardware, resulting in a dramatic
// performance gain.
//-----------------------------------------------------------------------------
HRESULT InitVB()
{
typedef struct {char r,g,b;}st;
g_pd3dDevice->CreateTexture(320,240,0,0,D3DFMT_R8G8B8,
D3DPOOL_MANAGED,&texture,NULL);
g_pd3dDevice->CreateOffscreenPlainSurface(4,4,D3DFMT_R8G8B8
,D3DPOOL_MANAGED,&surf,NULL);
texture->GetSurfaceLevel(0,&surf);
surf->LockRect(&lock,NULL,0);
st st3[]={{0,0,255,},{0,255,0,},{255,0,0,},{127,127,127,},
{255,0,0,},{0,0,255,},{127,127,127,},{0,255,0,},
{0,255,0,},{127,127,127,},{255,0,0,},{0,0,255},
{127,127,127,},{255,0,0,},{0,255,0,},{255,0,0,},
};
void *b,*c;
b=(void *)st3;
c=(void *)lock.pBits;
memcpy(c, b, sizeof(st3));
surf->UnlockRect();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 10, 10, 10 ), 1.0f, 0 );
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&back);
g_pd3dDevice->UpdateSurface(surf, NULL, back, NULL);
// 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 );
}
On Code::Blocks 13.12, I used the wizard to create a DX9 project by starting a new project. I specified the DX folder and it doesn't complain. An auto-generated .cpp appears and it's set to GUI application, file is not set to read-only mode, and I hit compile:
||=== Build: Debug in xxxxxxxx (compiler: GNU GCC Compiler) ===|
c:\program files\codeblocks\mingw\bin..\lib\gcc\mingw32\4.7.1......\libmingw32.a(main.o):main.c:(.text.startup+0xa7)||undefined reference to `WinMain#16'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|
Here's the full code that's auto-generated:
#include <windows.h>
#include <d3d9.h>
#define NOMINMAX
LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
HRESULT InitD3D( HWND hWnd )
{
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof( d3dpp ) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
return S_OK;
}
VOID Cleanup()
{
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
VOID Render()
{
if( NULL == g_pd3dDevice )
return;
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Rendering of scene objects can happen here
// 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;
case WM_PAINT:
Render();
ValidateRect( hWnd, NULL );
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, 0, 0,
GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL
};
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 01: CreateDevice",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, wc.hInstance, NULL );
// Initialize Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// Enter the message loop
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
UnregisterClass( "D3D Tutorial", wc.hInstance );
return 0;
}
Before the same questions are asked before in answers where this may have been solved, here's what's been tried:
1.Restarted Code::Blocks; still gives the same error.
2.Tried GUI and console; still gives the same error.
3.Tried with a blank application; still gives the same error.
4.Tried with a Windows GUI application; still gives the same error.
I am guaranteed that the DX SDK is setup and the runtime is up-to-date and everything else of the related such. Any other suggestions to this issue?
Replace this Microsoft monstrosity:
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
with this standard C++ code:
int main()
That's it.
Your code appears to already be written for a standard main, e.g. you're using GetModuleHandle( 0 ) instead of the hInst from wWinMain.
If you want UTF-16 encoded process command line, just call GetCommandLine, and possibly CommandLineToArgvW (IIRC) to parse it. MinGW-64 does support wmain, via a special option. But with the two functions mentioned you can implement the wmain support in five to six lines of code, so it doesn't really matter, and I'd rather write the code than using an obscure option.
I want to get a fast access to the pixels of a game which uses directX9 or 10. Therefore I used the D3D9 library. Do I have to use the D3D10 library when it is a directX10 game? If this is true, the next part is irrelevant.
The following code works except I'm only get zeros in qDebug("%.2f, %.2f, %.2f, %.2f", pixel[0].r, pixel[0].g, pixel[0].b, pixel[0].a); although it should have an other color and I have no clue why. Is there an error in swapping the data?
Initialization:
IDirect3D9 *m_d3d;
IDirect3DDevice9 *m_d3ddev;
D3DDISPLAYMODE *m_d3ddm;
HRESULT hr;
m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (m_d3d == NULL)
{
qFatal("Cannot create Direct3D!");
}
m_d3ddm = (D3DDISPLAYMODE *)calloc(1, sizeof(D3DDISPLAYMODE));
hr = m_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm);
if (hr != D3D_OK)
{
m_d3d->Release();
qFatal("Cannot get DisplayMode!");
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = m_target;
d3dpp.BackBufferWidth = m_d3ddm->Width;
d3dpp.BackBufferHeight = m_d3ddm->Height;
d3dpp.BackBufferFormat = m_d3ddm->Format;
hr = m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_target, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3ddev);
if (FAILED(hr))
{
m_d3d->Release();
qFatal("Failed CreateDevice!");
}
else
{
qDebug("Created Device with %i * %i", m_d3ddm->Width, m_d3ddm->Height);
}
Capture:
IDirect3DSurface9 *renderTarget= NULL;
IDirect3DSurface9 *destTarget = NULL;
hr = m_d3ddev->GetRenderTarget(0, &renderTarget);
if (FAILED(hr))
{
qFatal("Failed GetRenderTarget!");
}
hr = m_d3ddev->CreateOffscreenPlainSurface(m_d3ddm->Width, m_d3ddm->Height, m_d3ddm->Format, D3DPOOL_SYSTEMMEM, &destTarget, NULL);
if (FAILED(hr))
{
qFatal("Failed CreateOffscreenPlainSurface!");
}
hr = m_d3ddev->GetRenderTargetData(renderTarget, destTarget);
if (FAILED(hr))
{
qFatal("Failed GetRenderTargetData!");
}
D3DLOCKED_RECT lr;
ZeroMemory(&lr, sizeof(D3DLOCKED_RECT));
hr = destTarget->LockRect(&lr, 0, D3DLOCK_READONLY);
if (FAILED(hr))
{
qFatal("Cannot lock rect!");
}
ARGB *pixel = (ARGB *)lr.pBits;
if (!pixel)
{
qFatal("No data!");
}
qDebug("%.2f, %.2f, %.2f, %.2f", pixel[0].r, pixel[0].g, pixel[0].b, pixel[0].a);
hr = destTarget->UnlockRect();
if (FAILED(hr))
{
qFatal("Cannot unlock rect!");
}
renderTarget->Release();
destTarget->Release();
Cleaning
m_d3ddev->Release();
m_d3d->Release();
delete m_d3ddm;
delete m_d3d;
delete m_d3ddev;
This code is a simulation of what you should have.. It shows that the backbuffer is actually being captured. I created the device the exact same way you did. I capture the back-buffer the same way..
To test if the back-buffer is actually captured, I have set the window background to a navy-blue colour. Then when I call the capture function, I compare all the colours in the buffer to the original background colour.. This lets me know if a single pixel is different than the background..
If it is different, we "possibly" failed to capture the background. Otherwise, we are good..
I've tested the below and it indeed captures the backbuffer perfectly fine.. I even saved the backbuffer to a bitmap to see if it captures it and it does..
All in all, there's nothing wrong with your code, but I cannot guarantee that you are using it correctly.. In other words, you haven't shown me where you call your back-buffer capture code.. There are many places it can be called, but the best places are either in a hook to EndScene or a hook to Present. If you are using this on your own application, then call it in your onDraw/onUpdate function..
#include <tchar.h>
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <iostream>
HRESULT capture(IDirect3DDevice9* m_d3ddev, void* buffer, int& width, int& height, D3DFORMAT format);
void onUpdate(HWND hwnd, IDirect3D9* d3d9, IDirect3DDevice9* d3ddev9, D3DFORMAT format)
{
d3ddev9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev9->BeginScene();
//All drawing goes here..
d3ddev9->EndScene();
d3ddev9->Present(NULL, NULL, NULL, NULL); //Swaps the back and front buffers. Displays all drawing on the screen..
RECT rect;
GetClientRect(hwnd, &rect);
int width = rect.right - rect.left, height = rect.bottom - rect.top;
unsigned char* buffer = new unsigned char[width * height * 4];
capture(d3ddev9, buffer, width, height, format);
unsigned char* px = buffer;
for(int i = 0; i < height; ++i)
{
for(int j = 0; j < width; ++j)
{
unsigned char B = *px++;
unsigned char G = *px++;
unsigned char R = *px++;
unsigned char A = *px++;
if(D3DCOLOR_XRGB(R, G, B) != D3DCOLOR_XRGB(0, 40, 100))
{
MessageBox(NULL, "FAILED.. Colour differs from original background..", NULL, 0);
}
}
}
delete[] buffer;
}
int onDisplay(HWND hwnd)
{
IDirect3D9* d3d9 = NULL;
IDirect3DDevice9* d3ddev9 = NULL;
D3DPRESENT_PARAMETERS Parameters = {0};
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE* dispMode = new D3DDISPLAYMODE();
d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, dispMode);
Parameters.Windowed = true;
Parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
Parameters.hDeviceWindow = hwnd;
Parameters.BackBufferFormat = dispMode->Format;
d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &Parameters, &d3ddev9);
delete dispMode;
MSG messages;
ShowWindow(hwnd, SW_SHOW);
while(true)
{
if(PeekMessage(&messages, NULL, 0, 0, PM_REMOVE) > 0)
{
if(messages.message != WM_QUIT)
{
TranslateMessage(&messages);
DispatchMessageW(&messages);
continue;
}
break;
}
else
{
onUpdate(hwnd, d3d9, d3ddev9, Parameters.BackBufferFormat);
}
}
if(d3ddev9) d3ddev9->Release();
if(d3d9) d3d9->Release();
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = "D3DWindow";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if(!RegisterClassEx(&wincl)) return 0;
HWND hwnd = CreateWindowEx(0, "D3DWindow", "D3D9: Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
return onDisplay(hwnd);
}
HRESULT capture(IDirect3DDevice9* m_d3ddev, void* buffer, int& width, int& height, D3DFORMAT format)
{
IDirect3DSurface9 *renderTarget= NULL;
IDirect3DSurface9 *destTarget = NULL;
HRESULT hr = m_d3ddev->GetRenderTarget(0, &renderTarget);
hr = m_d3ddev->CreateOffscreenPlainSurface(width, height, format, D3DPOOL_SYSTEMMEM, &destTarget, NULL);
if(FAILED(hr))
{
printf("Failed CreateOffscreenPlainSurface!");
}
hr = m_d3ddev->GetRenderTargetData(renderTarget, destTarget);
if(FAILED(hr))
{
printf("Failed GetRenderTargetData!");
}
D3DLOCKED_RECT lr;
ZeroMemory(&lr, sizeof(D3DLOCKED_RECT));
hr = destTarget->LockRect(&lr, 0, D3DLOCK_READONLY);
if(FAILED(hr))
{
printf("Cannot lock rect!");
}
if(lr.pBits)
{
memcpy(buffer, lr.pBits, width * height * 4);
}
hr = destTarget->UnlockRect();
if(FAILED(hr))
{
printf("Cannot unlock rect!");
}
renderTarget->Release();
destTarget->Release();
return hr;
}
My compiler codeblocks gives me the following error when I try to compile my code:
c:\blah.cpp|67|error: 'SetLayeredWindowAttributes' was not declared in this scope
I am including windows.h so I don't see why this would happen. Here is the full code:
// main.cpp : Defines the entry point for the application. //
#include "C:\Program Files\Microsoft DirectX SDK (August 2008)\Include\D3dx9core.h"
#include "C:\Documents and Settings\Death\My Documents\Downloads\DXSprite\DXSprite\resource.h"
#include <windows.h>
#include <string>
#include <stdio.h> //----------------------------------------------------------------------------- // GLOBALS //----------------------------------------------------------------------------- HWND g_hWnd = NULL; LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; ID3DXSprite
* g_pD3DXSprite = NULL; LPDIRECT3DTEXTURE9 g_pTexture = NULL; const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600;
//----------------------------------------------------------------------------- // PROTOTYPES //----------------------------------------------------------------------------- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); HRESULT InitializeD3D ( ); void RenderFrame ( );
//----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow ) { WNDCLASSEX winClass; MSG uMsg; HRESULT hr;
memset(&uMsg,0,sizeof(uMsg));
winClass.lpszClassName = "MY_WINDOWS_CLASS"; winClass.cbSize
= sizeof(WNDCLASSEX); winClass.style = CS_HREDRAW | CS_VREDRAW; winClass.lpfnWndProc = WindowProc; winClass.hInstance
= hInstance; winClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDC_DXSPRITE);
winClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDC_DXSPRITE); winClass.hCursor = LoadCursor(NULL, IDC_ARROW); winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winClass.lpszMenuName = NULL; winClass.cbClsExtra = 0; winClass.cbWndExtra = 0;
if( !RegisterClassEx(&winClass) ) return E_FAIL;
g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS",
"Direct3D 9 - ID3DXSprite Example",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL );
if( g_hWnd == NULL ) return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
UpdateWindow( g_hWnd ); SetLayeredWindowAttributes(GetActiveWindow(), NULL, 255, LWA_ALPHA); //---------------------------------------------------------------- // Create the DirectX device //---------------------------------------------------------------- if (FAILED( InitializeD3D())) return 0;
//---------------------------------------------------------------- // CREATE THE ID3DXSprite //----------------------------------------------------------------
// Create the ID3DXSprite interface object hr = D3DXCreateSprite(g_pD3DDevice, &g_pD3DXSprite ); if( FAILED(hr) ) return hr;
//---------------------------------------------------------------- // LOAD THE TEXTURE FOR THE SPRITE //----------------------------------------------------------------
// -------------------------------------------------------- // Load the texture. I decided to use the extended // version of the texture loading function just to show what // it would look like. // The texture was created with Photoshop with a transparent // background to start with. Then line cross hairs were added. // // Note - If you don't use a texture image that has a power of // 2 size for the width or height then the image may not load // properly. This image is 256x256. //
D3DXCreateTextureFromFileEx( g_pD3DDevice, "C:\\Documents and Settings\\Death\\My Documents\\45handold2.tga", // Our texture image! D3DX_DEFAULT, // width D3DX_DEFAULT, // height D3DX_DEFAULT, // MIP levels 0, // usage D3DFMT_DXT1, // texture format D3DPOOL_MANAGED, // mem pool D3DX_DEFAULT, // filter D3DX_DEFAULT, // MIP filter 0, // transparent color key NULL, // image info struct NULL, // palette &g_pTexture); // the returned texture, if success
if ( FAILED(hr) ) return hr;
// --------- // Main Loop // --------- while( uMsg.message != WM_QUIT ) { if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &uMsg ); DispatchMessage( &uMsg ); } }
// ------------------------- // Release directx resources //
------------------------- if (g_pD3DXSprite) { g_pD3DXSprite->Release(); g_pD3DXSprite = NULL; }
if (g_pTexture) { g_pTexture->Release(); g_pTexture = NULL; }
if (g_pD3DDevice) { g_pD3DDevice->Release(); g_pD3DDevice = NULL; }
UnregisterClass( "MY_WINDOWS_CLASS", winClass.hInstance ); return (int)uMsg.wParam; }
//----------------------------------------------------------------------------- // Name: WindowProc() // Desc: The window's message handler //----------------------------------------------------------------------------- LRESULT CALLBACK WindowProc( HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam ) {
switch( msg ) {
case WM_KEYDOWN: { switch( wParam ) {
case VK_ESCAPE:
PostQuitMessage(0);
break;
} }
break;
case WM_CLOSE: { PostQuitMessage(0); }
case WM_DESTROY: {
PostQuitMessage(0); }
break;
default: {
RenderFrame(); return DefWindowProc( hWnd, msg, wParam, lParam ); } break; }
return 0; }
//----------------------------------------------------------------------------- // Name: InitializeD3D() // Desc: Create DirectX interface objects // Initialize the view matrix. // Setup render states that will not need changing throughout // the life of the application. //----------------------------------------------------------------------------- HRESULT InitializeD3D( ) { HRESULT hr;
// Create a direct 3D interface object
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if( g_pD3D == NULL ) { // TO DO: Respond to failure of Direct3DCreate9 return E_FAIL; }
D3DDISPLAYMODE d3ddm;
if( FAILED( hr = g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) ) { // TO DO: Respond to failure of GetAdapterDisplayMode return hr; }
// if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) { if( hr == D3DERR_NOTAVAILABLE ) // POTENTIAL PROBLEM: We need at least a 16-bit z-buffer! return hr; }
// // Do we support hardware vertex processing? If so, use it. // If not, downgrade to software. //
D3DCAPS9 d3dCaps;
if( FAILED( hr = g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, &d3dCaps ) ) ) { // TO DO: Respond to failure of GetDeviceCaps return hr; }
DWORD dwBehaviorFlags = 0;
if( d3dCaps.VertexProcessingCaps != 0 ) dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; else dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// // Everything checks out - create a simple, windowed device. //
D3DPRESENT_PARAMETERS d3dpp; memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.BackBufferFormat = d3ddm.Format; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
// Attempt to create a HAL device, end app on failure just to keep things // simple. In other words we are not trying to create a REF device if the // HAL fails.
if( FAILED( hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, HWND_DESKTOP,
dwBehaviorFlags, &d3dpp, &g_pD3DDevice ) ) ) { // char blah[100];
// snprintf (blah, 1000, "%d", hr); //MessageBox (NULL,blah,NULL,NULL); }
// If we get here everything worked! return S_OK; }
//----------------------------------------------------------------------------- // Name: RenderFrame() // Desc: Draw the image to the framebuffer. //----------------------------------------------------------------------------- void RenderFrame( ) { if (!g_pD3DDevice && !g_pD3DXSprite && !g_pTexture) return;
// Clear the frame & depth buffer ready for drawing (Black color)
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
g_pD3DDevice->BeginScene(); { //------------------------- // Render the sprite //
D3DXVECTOR3 vecPos = D3DXVECTOR3(0,0,0);
if (g_pD3DXSprite && g_pTexture) { g_pD3DXSprite->Begin( D3DXSPRITE_ALPHABLEND ); g_pD3DXSprite->Draw(g_pTexture, NULL, NULL, &vecPos, 0xffffffff); g_pD3DXSprite->End(); }
} g_pD3DDevice->EndScene();
// Frame buffer to Front buffer g_pD3DDevice->Present( NULL, NULL, NULL, NULL );
}
You need to add #define _WIN32_WINNT 0x0501 before including windows.h, as SetLayeredWindowAttributes is only declared when _WIN32_WINNT >= 0x0500.
I'm trying to use MSDN's Direct2D basic tutorial, but the window won't show up, it output's the normal debug info, but no window. I've tried playing about with the WinMain() parameters and the ShowWindow() function, but it still refuses to work. Allso in the debug info there's this, but i don't think it's relevant. \NVIDIA Corporation\coprocmanager\nvdxgiwrap.dll'. Cannot find or open the PDB file.
Here's the code.
#include "RenderHeader.h"
//Main window function.
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */)
{
// Use HeapSetInformation to specify that the process should
// terminate if the heap manager detects an error in any heap used
// by the process.
// The return value is ignored, because we want to continue running in the
// unlikely event that HeapSetInformation fails.
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
if (SUCCEEDED(CoInitialize(NULL)))
{
{
GameRender app;
if (SUCCEEDED(app.Initialize()))
{
//Runs the application message loop.
app.RunMessageLoop();
}
}
CoUninitialize();
}
return 0;
}
GameRender::GameRender() :
m_hwnd(NULL),
m_pDirect2DFactory(NULL),
m_pRenderTarget(NULL),
m_pLightSlateGrayBrush(NULL),
m_pCornflowerBlueBrush(NULL)
{
}
GameRender::~GameRender()
{
SafeRelease(&m_pDirect2DFactory);
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
HRESULT GameRender::Initialize()
{
HRESULT hRes;
/* Initialize device-indpendent resources, such
as the Direct2D factory.*/
hRes = CreateDeviceIndependantResources();
if (SUCCEEDED(hRes))
{
WNDCLASSEX Window = { sizeof(WNDCLASSEX) } ;
Window.style = CS_HREDRAW | CS_VREDRAW;
Window.lpfnWndProc = GameRender::WndProc;
Window.cbClsExtra = 0;
Window.cbWndExtra = sizeof(LONG_PTR);
Window.hInstance = HINST_THISCOMPONENT;
Window.hbrBackground = NULL;
Window.lpszMenuName = NULL;
Window.hCursor = LoadCursor(NULL, IDI_APPLICATION);
Window.lpszClassName = L"D2DDemoApp";
RegisterClassEx(&Window);
/* Because the CreateWindow function takes its size in pixels,
obtain the system DPI and use it to scale the window size.*/
FLOAT DpiX, DpiY;
/* The factory returns the current system DPI. This is also the value it will use
to create its own windows.*/
m_pDirect2DFactory->GetDesktopDpi(&DpiX, &DpiY);
//Create Window
m_hwnd = CreateWindow(L"D2PDemoApp",
L"Direct 2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * DpiX / 96.f)),
static_cast<UINT>(ceil(480.f * DpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this);
hRes = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hRes))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
}
return hRes;
}
HRESULT GameRender::CreateDeviceIndependantResources()
{
HRESULT hr = S_OK;
//Create a direct2D Factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2DFactory);
return hr;
}
HRESULT GameRender::CreateDeviceDependantResources()
{
HRESULT hr = S_OK;
if(!&m_pRenderTarget)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
//Create a render target.
hr = m_pDirect2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(m_hwnd, size), &m_pRenderTarget);
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
&m_pLightSlateGrayBrush);
}
if (SUCCEEDED(hr))
{
// Create a blue brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
&m_pCornflowerBlueBrush
);
}
}
return hr;
}
void GameRender::DiscardDeviceResources()
{
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
void GameRender::RunMessageLoop()
{
MSG Message;
while (GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
HRESULT GameRender::OnDraw()
{
HRESULT hr = S_OK;
hr = CreateDeviceDependantResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
// Draw a grid background.
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
for (int x = 0; x < width; x += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
m_pLightSlateGrayBrush,
0.5f
);
}
for (int y = 0; y < height; y += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
m_pLightSlateGrayBrush,
0.5f
);
}
// Draw two rectangles.
D2D1_RECT_F rectangle1 = D2D1::RectF(
rtSize.width/2 - 50.0f,
rtSize.height/2 - 50.0f,
rtSize.width/2 + 50.0f,
rtSize.height/2 + 50.0f
);
D2D1_RECT_F rectangle2 = D2D1::RectF(
rtSize.width/2 - 100.0f,
rtSize.height/2 - 100.0f,
rtSize.width/2 + 100.0f,
rtSize.height/2 + 100.0f
);
// Draw a filled rectangle.
m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
// Draw the outline of a rectangle.
m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);
hr = m_pRenderTarget->EndDraw();
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
void GameRender::OnResize(UINT width, UINT height)
{
if (m_pRenderTarget)
{
// Note: This method can fail, but it's okay to ignore the
// error here, because the error will be returned again
// the next time EndDraw is called.
m_pRenderTarget->Resize(D2D1::SizeU(width,
height));
}
}
LRESULT CALLBACK GameRender::WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
GameRender *pGameRender = (GameRender *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pGameRender)
);
result = 1;
}
else
{
GameRender *pGameRender = reinterpret_cast<GameRender *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pGameRender)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pGameRender->OnResize(width, height);
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pGameRender->OnDraw();
ValidateRect(hwnd, NULL);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}
Assuming that "RenderHeader.h" exists in your project's directory and it includes the windows header, then your problem is that you're not passing WinMain the variables it needs to function. 'HINSTANCE', 'LPSTR' and 'int' are all variable types, but you need to give them a name, otherwise they don't exist and the function won't work.
So this would be right
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int uCmdShow )
{
// The rest of the code
}
The names of the variables are commented out on the code in your question :P