//----------------------------------------------------------------------------- // File: Textures.cpp // // Desc: Better than just lights and materials, 3D objects look much more // convincing when texture-mapped. Textures can be thought of as a sort // of wallpaper, that is shrinkwrapped to fit a texture. Textures are // typically loaded from image files, and D3DX provides a utility to // function to do this for us. Like a vertex buffer, textures have // Lock() and Unlock() functions to access (read or write) the image // data. Textures have a width, height, miplevel, and pixel format. The // miplevel is for "mipmapped" textures, an advanced performance- // enhancing feature which uses lower resolutions of the texture for // objects in the distance where detail is less noticeable. The pixel // format determines how the colors are stored in a texel. The most // common formats are the 16-bit R5G6B5 format (5 bits of red, 6-bits of // green and 5 bits of blue) and the 32-bit A8R8G8B8 format (8 bits each // of alpha, red, green, and blue). // // Textures are associated with geometry through texture coordinates. // Each vertex has one or more sets of texture coordinates, which are // named tu and tv and range from 0.0 to 1.0. Texture coordinates can be // supplied by the geometry, or can be automatically generated using // Direct3D texture coordinate generation (which is an advanced feature). // // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #include #include #include #include #include #pragma warning( disable : 4996 ) // disable deprecated warning #include #pragma warning( default : 4996 ) typedef struct _D3DKMT_OPENADAPTERFROMDEVICENAME { wchar_t *pDeviceName; HANDLE hAdapter; LUID AdapterLuid; } D3DKMT_OPENADAPTERFROMDEVICENAME; typedef struct _D3DKMT_CLOSEADAPTER { HANDLE hAdapter; } D3DKMT_CLOSEADAPTER; typedef struct _D3DKMT_QUERYADAPTERINFO { HANDLE hAdapter; unsigned int Type; void *pPrivateDriverData; unsigned int PrivateDriverDataSize; } D3DKMT_QUERYADAPTERINFO; typedef struct _D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME { WCHAR DeviceName[32]; HANDLE hAdapter; LUID AdapterLuid; unsigned int VidPnSourceId; } D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME; typedef struct _D3DKMT_SEGMENTSIZEINFO { ULONGLONG DedicatedVideoMemorySize; ULONGLONG DedicatedSystemMemorySize; ULONGLONG SharedSystemMemorySize; } D3DKMT_SEGMENTSIZEINFO; typedef struct _D3DKMT_ADAPTERREGISTRYINFO { WCHAR AdapterString[MAX_PATH]; WCHAR BiosString[MAX_PATH]; WCHAR DacType[MAX_PATH]; WCHAR ChipType[MAX_PATH]; } D3DKMT_ADAPTERREGISTRYINFO; typedef int (APIENTRY *PFND3DKMT_CLOSEADAPTER)(IN CONST D3DKMT_CLOSEADAPTER *pData); typedef int (APIENTRY *PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)(IN OUT D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *pData); typedef int (__stdcall *PFNDWM_DXGETWINDOWSHAREDSURFACE)(HWND hWnd, LUID adapterLuid, DWORD one, DWORD two, DWORD *pD3DFormat, HANDLE *pSharedHandle, unsigned __int64 *arg7); typedef int (__stdcall *PFNDWM_DwmEnableMMCSS)(unsigned __int64 arg); typedef int (__stdcall *PFNDWM_DwmpDxUpdateWindowSharedSurface)(HWND hWnd, int, int, int, HMONITOR hMonitor, void* test); typedef int (__stdcall *PFNDWM_DwmStartRedirection)(void *, int); typedef int (__stdcall *PFNDWM_DwmStopRedirection)(HWND hWnd); typedef int (__stdcall *PFNDWM_DwmHintUpdate)(DWORD dword); typedef int (__stdcall *PFNDWM_DwmGetSurfaceData)(HANDLE h, HWND hWnd); typedef int (__stdcall *PFNDWM_DwmGetDirtyRgn)(HWND hWnd, RECT* rect); static PFNDWM_DwmpDxUpdateWindowSharedSurface pDwmpDxUpdateWindowSharedSurface = NULL; static PFNDWM_DwmStartRedirection pDwmStartRedirection = NULL; static PFNDWM_DwmStopRedirection pDwmStopRedirection = NULL; static PFNDWM_DwmHintUpdate pDwmHintUpdate = NULL; static PFNDWM_DwmGetSurfaceData pDwmGetSurfaceData = NULL; static PFNDWM_DwmGetDirtyRgn pDwmGetDirtyRgn = NULL; unsigned __int64 unknown = 0; int counter2 = 0; LUID adapterLuid = { 0, 0 }; void GetWindowSharedSurfaceHandle(HWND hWnd, HANDLE *sharedHandle, DWORD *d3dFormat) { HMONITOR hMonitor = NULL; LUID nullLuid = { 0, 0 }; MONITORINFOEX monitorInfo; D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME openDev; D3DKMT_CLOSEADAPTER closeDev; static PFNDWM_DXGETWINDOWSHAREDSURFACE pDwmpDxGetWindowSharedSurface = NULL; static PFNDWM_DwmEnableMMCSS pDwmEnableMMCSS = NULL; static PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME pOpenAdapterFromGdiDisplayName = NULL; static PFND3DKMT_CLOSEADAPTER pCloseAdapter = NULL; static int pDwmpFlush = NULL; hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); monitorInfo.cbSize = sizeof(monitorInfo); GetMonitorInfo(hMonitor, &monitorInfo); if (pOpenAdapterFromGdiDisplayName == NULL || pCloseAdapter == NULL || pDwmpDxGetWindowSharedSurface == NULL) { HMODULE hGdi = LoadLibrary(L"gdi32.dll"); pOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(hGdi, "D3DKMTOpenAdapterFromGdiDisplayName"); pCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(hGdi, "D3DKMTCloseAdapter"); pDwmGetSurfaceData = (PFNDWM_DwmGetSurfaceData)GetProcAddress(hGdi, "DwmGetSurfaceData"); pDwmGetDirtyRgn = (PFNDWM_DwmGetDirtyRgn)GetProcAddress(hGdi, "DwmGetDirtyRgn"); HMODULE hDwmApi = LoadLibrary(L"dwmapi.dll"); pDwmpDxGetWindowSharedSurface = (PFNDWM_DXGETWINDOWSHAREDSURFACE)GetProcAddress(hDwmApi, (LPCSTR)100); pDwmEnableMMCSS = (PFNDWM_DwmEnableMMCSS)GetProcAddress(hDwmApi, (LPCSTR)117); pDwmpDxUpdateWindowSharedSurface = (PFNDWM_DwmpDxUpdateWindowSharedSurface)GetProcAddress(hDwmApi, (LPCSTR)101); HMODULE hUser32 = LoadLibrary(L"user32.dll"); pDwmStartRedirection = (PFNDWM_DwmStartRedirection)GetProcAddress(hDwmApi, (LPCSTR)106); pDwmStopRedirection = (PFNDWM_DwmStopRedirection)GetProcAddress(hDwmApi, (LPCSTR)205); pDwmHintUpdate = (PFNDWM_DwmHintUpdate)GetProcAddress(hUser32, (LPCSTR)202); } memcpy(&openDev.DeviceName, monitorInfo.szDevice, 32); HRESULT hr; hr = pOpenAdapterFromGdiDisplayName(&openDev); adapterLuid = openDev.AdapterLuid; closeDev.hAdapter = openDev.hAdapter; hr = pCloseAdapter(&closeDev); DWORD x = (DWORD)hMonitor; unknown = 55; hr = pDwmpDxGetWindowSharedSurface(hWnd, adapterLuid, 0, 0, d3dFormat, sharedHandle, &unknown); counter2++; } //----------------------------------------------------------------------------- // Global variables //----------------------------------------------------------------------------- LPDIRECT3D9EX g_pD3D = NULL; // Used to create the D3DDevice LPDIRECT3DDEVICE9EX g_pd3dDevice = NULL; // Our rendering device LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture // A structure for our custom vertex type. We added texture coordinates struct CUSTOMVERTEX { D3DXVECTOR3 position; // The position D3DCOLOR color; // The color #ifndef SHOW_HOW_TO_USE_TCI FLOAT tu, tv; // The texture coordinates #endif }; // Our custom FVF, which describes our custom vertex structure #ifdef SHOW_HOW_TO_USE_TCI #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE) #else #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) #endif HWND myHwnd; //----------------------------------------------------------------------------- // Name: InitD3D() // Desc: Initializes Direct3D //----------------------------------------------------------------------------- HRESULT InitD3D( HWND hWnd ) { myHwnd = hWnd; // Create the D3D object. HRESULT hr; hr = Direct3DCreate9Ex( D3D_SDK_VERSION, &g_pD3D ); if(hr != 0) return E_FAIL; // Set up the structure used to create the D3DDevice. Since we are now // using more complex geometry, we will create a device with a zbuffer. 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; d3dpp.hDeviceWindow = hWnd; d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; // Create the D3DDevice if( FAILED( g_pD3D->CreateDeviceEx( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_ENABLE_PRESENTSTATS, &d3dpp, NULL, &g_pd3dDevice ) ) ) { return E_FAIL; } // 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; } //----------------------------------------------------------------------------- // Name: InitGeometry() // Desc: Create the textures and vertex buffers //----------------------------------------------------------------------------- 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; } } // Create the vertex buffer. if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*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<50; i++ ) { FLOAT theta = (2*D3DX_PI*i)/(50-1); pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) ); pVertices[2*i+0].color = 0xffffffff; #ifndef SHOW_HOW_TO_USE_TCI pVertices[2*i+0].tu = ((FLOAT)i)/(50-1); pVertices[2*i+0].tv = 1.0f; #endif pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) ); pVertices[2*i+1].color = 0xff808080; #ifndef SHOW_HOW_TO_USE_TCI pVertices[2*i+1].tu = ((FLOAT)i)/(50-1); pVertices[2*i+1].tv = 0.0f; #endif } 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: SetupMatrices() // Desc: Sets up the world, view, and projection transform matrices. //----------------------------------------------------------------------------- VOID SetupMatrices() { // Set up world matrix D3DXMATRIXA16 matWorld; D3DXMatrixIdentity( &matWorld ); D3DXMatrixRotationY( &matWorld, timeGetTime()/2000.0f ); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction. D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered). D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } int counter = 0; int count3 = 0; //----------------------------------------------------------------------------- // Name: Render() // Desc: Draws the scene //----------------------------------------------------------------------------- VOID Render() { counter++; HANDLE texHandle = NULL; DWORD fmt = 0; RECT winRect; HWND h; HRESULT hr; if(counter > 100) { h = FindWindow(NULL, L"Window Directx ou WPF"); //"Direct3D9EX Sample //h = myHwnd; GetWindowRect(h, &winRect); HRESULT res; SIZE sWin = { winRect.right - winRect.left, winRect.bottom - winRect.top }; GetWindowSharedSurfaceHandle(h, &texHandle, &fmt); IDirect3DTexture9 * tex; IDirect3DTexture9 *texture; hr = g_pd3dDevice->CreateTexture(sWin.cx, sWin.cy, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)fmt, D3DPOOL_DEFAULT, &g_pTexture, &texHandle); PHTHUMBNAIL thumb; if(hr == 0) { hr = 0; } int val = 0; count3++; } int test = 0; if(counter > 100) { int size = sizeof(RECT); HMONITOR mon = MonitorFromWindow(h, MONITOR_DEFAULTTONEAREST); GetWindowRect(h, &winRect); SIZE sWin = { winRect.right - winRect.left, winRect.bottom - winRect.top }; MONITORINFO monitor; monitor.cbSize = sizeof(MONITORINFO); GetMonitorInfo(mon, &monitor); int x = 10; hr = pDwmpDxUpdateWindowSharedSurface(h, 0, 0, 0, 0, 0); x = 5; } // Clear the backbuffer and the zbuffer g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 10000, 1.0f, 0 ); // Begin the scene if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { // Setup the world, view, and projection matrices SetupMatrices(); // 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, NULL ); 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 ); #ifdef SHOW_HOW_TO_USE_TCI // Note: to use D3D texture coordinate generation, use the stage state // D3DTSS_TEXCOORDINDEX, as shown below. In this example, we are using // the position of the vertex in camera space (D3DTSS_TCI_CAMERASPACEPOSITION) // to generate texture coordinates. Camera space is the vertex position // multiplied by the World and View matrices. The tex coord index (TCI) // parameters are passed into a texture transform, which is a 4x4 matrix // which transforms the x,y,z TCI coordinates into tu, tv texture coordinates. // In this example, the texture matrix is setup to transform the input // camera space coordinates (all of R^3) to projection space (-1,+1) // and finally to texture space (0,1). // CameraSpace.xyzw = (input vertex position) * (WorldView) // ProjSpace.xyzw = CameraSpace.xyzw * Projection //move to -1 to 1 // TexSpace.xyzw = ProjSpace.xyzw * ( 0.5, -0.5, 1.0, 1.0 ) //scale to -0.5 to 0.5 (flip y) // TexSpace.xyzw += ( 0.5, 0.5, 0.0, 0.0 ) //shift to 0 to 1 // Setting D3DTSS_TEXTURETRANSFORMFLAGS to D3DTTFF_COUNT4 | D3DTTFF_PROJECTED // tells D3D to divide the input texture coordinates by the 4th (w) component. // This divide is necessary when performing a perspective projection since // the TexSpace.xy coordinates prior to the homogeneous divide are not actually // in the 0 to 1 range. D3DXMATRIXA16 mTextureTransform; D3DXMATRIXA16 mProj; D3DXMATRIXA16 mTrans; D3DXMATRIXA16 mScale; g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &mProj ); D3DXMatrixTranslation( &mTrans, 0.5f, 0.5f, 0.0f ); D3DXMatrixScaling( &mScale, 0.5f, -0.5f, 1.0f ); mTextureTransform = mProj * mScale * mTrans; g_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &mTextureTransform ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION ); #endif // Render the vertex buffer contents g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 ); // End the scene g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display g_pd3dDevice->PresentEx( NULL, NULL, NULL, NULL, NULL ); //g_pTexture->Release(); //CloseHandle(texHandle); } //----------------------------------------------------------------------------- // 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: WinMain() // 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 05:", WS_POPUP | WS_SIZEBOX, 100, 100, 800, 600, NULL, NULL, wc.hInstance, NULL ); MARGINS g_mgDWMMargins = {-1, -1, -1, -1}; // Initialize Direct3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { // Create the scene geometry 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; }