// 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
);
}
This is the sample in the documentation. I've included "D2d1.h", I just don't know how to create a "m_pRenderTarget". I'm writing a Kinect project, I want to draw a line on the image. I'm really new, please help me.
Have you see this page?
Create an ID2D1HwndRenderTarget
The quick start tutorial has a detail steps of how to use Direct2D.
You can also download the Windows SDK, the samples contains Direct2D demo which has the full steps of how to create Direct2D render target
I have write a program to draw a rectangle, with a little change, it can draw a line, just for your reference
#include <windows.h>
#include <D2D1.h>
#define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;}
ID2D1Factory* g_pD2DFactory = NULL; // Direct2D factory
ID2D1HwndRenderTarget* g_pRenderTarget = NULL; // Render target
ID2D1SolidColorBrush* g_pBlackBrush = NULL; // A black brush, reflect the line color
VOID CreateD2DResource(HWND hWnd)
{
if (!g_pRenderTarget)
{
HRESULT hr ;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory) ;
if (FAILED(hr))
{
MessageBox(hWnd, "Create D2D factory failed!", "Error", 0) ;
return ;
}
// Obtain the size of the drawing area
RECT rc ;
GetClientRect(hWnd, &rc) ;
// Create a Direct2D render target
hr = g_pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
hWnd,
D2D1::SizeU(rc.right - rc.left,rc.bottom - rc.top)
),
&g_pRenderTarget
) ;
if (FAILED(hr))
{
MessageBox(hWnd, "Create render target failed!", "Error", 0) ;
return ;
}
// Create a brush
hr = g_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&g_pBlackBrush
) ;
if (FAILED(hr))
{
MessageBox(hWnd, "Create brush failed!", "Error", 0) ;
return ;
}
}
}
VOID DrawLine(HWND hwnd)
{
CreateD2DResource(hwnd) ;
g_pRenderTarget->BeginDraw() ;
// Clear background color to White
g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
// Draw Rectangle
g_pRenderTarget->DrawLine(
D2D1::Point2F(100.0f, 100.0f),
D2D1::Point2F(500.0f, 500.0f),
g_pBlackBrush
);
HRESULT hr = g_pRenderTarget->EndDraw() ;
if (FAILED(hr))
{
MessageBox(NULL, "Draw failed!", "Error", 0) ;
return ;
}
}
VOID Cleanup()
{
SAFE_RELEASE(g_pRenderTarget) ;
SAFE_RELEASE(g_pBlackBrush) ;
SAFE_RELEASE(g_pD2DFactory) ;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
DrawLine(hwnd) ;
return 0 ;
case WM_KEYDOWN:
{
switch( wParam )
{
case VK_ESCAPE:
SendMessage( hwnd, WM_CLOSE, 0, 0 );
break ;
default:
break ;
}
}
break ;
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{
WNDCLASSEX winClass ;
winClass.lpszClassName = "Direct2D";
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW;
winClass.lpfnWndProc = WndProc;
winClass.hInstance = hInstance;
winClass.hIcon = NULL ;
winClass.hIconSm = NULL ;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = NULL ;
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
if (!RegisterClassEx (&winClass))
{
MessageBox ( NULL, TEXT( "This program requires Windows NT!" ), "error", MB_ICONERROR) ;
return 0 ;
}
HWND hwnd = CreateWindowEx(NULL,
"Direct2D", // window class name
"Draw Rectangle", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
600, // initial x size
600, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
MSG msg ;
ZeroMemory(&msg, sizeof(msg)) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
Related
I created two devices A and B, where A is the producer and B is the consumer. The texture is shared between the two through D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX. Now I find that every time B calls CopyResource to copy the shared texture to the local, the video memory will keep increasing. This The problem has troubled me for a long time. I searched github or other code sources, but couldn’t find a solution. My machine is Win10 and Geforce GTX 1060.
The most streamlined code to reproduce the problem is as follows:
#include <dxgi.h>
#include <d3d11.h>
#include <atlbase.h>
#pragma comment(lib, "D3D11.lib")
#define RETURN_ON_FAIL(hr) if(FAILED(hr)) return hr;
namespace SharedTextureLeakTest
{
const UINT32 texture_width = 320;
const UINT32 texture_height = 240;
ATL::CComPtr<ID3D11Device> device_1 = nullptr;
ATL::CComPtr<ID3D11DeviceContext> context_1 = nullptr;
ATL::CComPtr<ID3D11Device> device_2 = nullptr;
ATL::CComPtr<ID3D11DeviceContext> context_2 = nullptr;
ATL::CComPtr<ID3D11Texture2D> shared_texture_dev1 = nullptr; //owner by device1
ATL::CComPtr<ID3D11Texture2D> dst_texture_dev2 = nullptr; //owner by device2
HANDLE shared_handle = nullptr;
HRESULT CheckEnvironmentValid()
{
HRESULT hr = S_OK;
//Create Device1
if (!device_1)
{
D3D_FEATURE_LEVEL pFeatureLevel;
UINT Flags = D3D11_CREATE_DEVICE_DEBUG;
hr = ::D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, Flags, nullptr, 0, D3D11_SDK_VERSION, &device_1, &pFeatureLevel, &context_1);
if (FAILED(hr))
{
device_1 = nullptr;
return hr;
}
}
//Create Shared Texture
if (!shared_texture_dev1)
{
D3D11_TEXTURE2D_DESC desc;
desc.ArraySize = 1;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.Width = texture_width;
desc.Height = texture_height;
desc.MipLevels = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
hr = device_1->CreateTexture2D(&desc, nullptr, &shared_texture_dev1);
RETURN_ON_FAIL(hr);
}
//Get Handle of Shared Texture
if (!shared_handle)
{
ATL::CComPtr<IDXGIResource> dxgi_res;
hr = shared_texture_dev1->QueryInterface(__uuidof(IDXGIResource), (void**)&dxgi_res);
RETURN_ON_FAIL(hr);
hr = dxgi_res->GetSharedHandle(&shared_handle);
RETURN_ON_FAIL(hr);
}
//Create Device2
if (!device_2)
{
D3D_FEATURE_LEVEL pFeatureLevel;
UINT Flags = D3D11_CREATE_DEVICE_DEBUG;
hr = ::D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, Flags, nullptr, 0, D3D11_SDK_VERSION, &device_2, &pFeatureLevel, &context_2);
if (FAILED(hr))
{
device_2= nullptr;
return hr;
}
}
//Create Dst Texture
if (!dst_texture_dev2)
{
D3D11_TEXTURE2D_DESC desc;
desc.ArraySize = 1;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.Width = texture_width;
desc.Height = texture_height;
desc.MipLevels = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = 0;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
hr = device_2->CreateTexture2D(&desc, nullptr, &dst_texture_dev2);
RETURN_ON_FAIL(hr);
}
return hr;
}
HRESULT LoopOnceTest()
{
HRESULT hr = CheckEnvironmentValid();
RETURN_ON_FAIL(hr);
//Open Shared Texture
ATL::CComPtr<ID3D11Texture2D> shared_texture_dev2;
hr = device_2->OpenSharedResource(shared_handle, IID_PPV_ARGS(&shared_texture_dev2));
RETURN_ON_FAIL(hr);
//Copy
do
{
CComPtr<IDXGIKeyedMutex> km;
hr = shared_texture_dev2->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&km);
RETURN_ON_FAIL(hr);
INT64 release_key = 0;
hr = km->AcquireSync(0, 10);
RETURN_ON_FAIL(hr);
if (hr == WAIT_OBJECT_0)
{
context_2->CopyResource(dst_texture_dev2, shared_texture_dev2);
// context_2->Flush();
}
hr = km->ReleaseSync(0);
RETURN_ON_FAIL(hr);
} while (FALSE);
return hr;
}
}
void DoTest()
{
for(;;)
{
SharedTextureLeakTest::LoopOnceTest();
Sleep(1000);
}
}
my program is a transparent overlay over a game
code that sets it to the game window
setwindowtotarget is called in a seperate thread
i am very frusturated
also, the game feels laggy when my fps counter says i'm getting over 200 as well
void SetWindowToTarget(){
while(true){
tWnd = FindWindow(0, tWindowName);
if (tWnd)
{
GetWindowRect(tWnd, &tSize);
Width = tSize.right - tSize.left;
Height = tSize.bottom - tSize.top;
DWORD dwStyle = GetWindowLong(tWnd, GWL_STYLE);
if(dwStyle & WS_BORDER)
{
tSize.top += 23;
Height -= 23;
}
MoveWindow(hWnd, tSize.left, tSize.top, Width, Height, true);
}
Sleep(5000);
}
}
this code makes my fps drop down and then back up every 10 seconds or so
while (GetMessage(&Message, NULL, 0, 0)){
TranslateMessage(&Message);
DispatchMessage(&Message);
}
LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam){
Sleep(17);
switch (Message)
{
case WM_PAINT:
Render();
break;
case WM_CREATE:
DwmExtendFrameIntoClientArea(hWnd, &Margin);
break;
case WM_DESTROY:
PostQuitMessage(1);
return 0;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
break;
}
return 0;
}
render func:
int Render(){
p_Device->Clear(0, 0, D3DCLEAR_TARGET, 0, 1.0f, 0);
p_Device->BeginScene();
if(tWnd == GetForegroundWindow()){
g_vCenterScreen.x = Width / 2.f;
g_vCenterScreen.y = Height / 2.f;
//draw stuff
}
}
p_Device->EndScene();
p_Device->PresentEx(0, 0, 0, 0, 0);
return 0;
}
i'm trying to hook Direct x 9.
I used below code for hook dll, and i injected the dll for my dx game.
But there has a crash in my dx game.
So.. May i get some helps? I have no idea why it does not work.
Maybe i guess the h_EndScene(LPDIRECT3DDEVICE9 pDevice) function's
return org_EndScene(pDevice); cause crash.
(but there is nothing to strange... )
//Dll's Main.cpp
#include "d3dhooks.h"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hinstDLL);
StartD3DHooks();
return true;
break;
}
case DLL_PROCESS_DETACH:
{
MessageBox(NULL,L"detach dll!", L"ok", MB_OK);
break;
}
}
return TRUE;
}
//d3dhooks.h
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "d3dx9.lib" )
#include <iostream>
#include <vector>
class DXGH
{
public:
static HRESULT WINAPI h_EndScene(LPDIRECT3DDEVICE9 pDevice);
void DrawRect(LPDIRECT3DDEVICE9 Device_t, int X, int Y, int L, int H,
D3DCOLOR color);
};
int StartD3DHooks();
typedef HRESULT(WINAPI *EndScene_t)(LPDIRECT3DDEVICE9 pDevice);
extern DXGH DXGameHook;
//d3dhooks.cpp
#include "d3dhooks.h"
#define ENDSCENE 42
DXGH DXGameHook;
typedef HRESULT(__stdcall* EndScene_t)(LPDIRECT3DDEVICE9);
EndScene_t org_EndScene;
const D3DCOLOR txtPink = D3DCOLOR_ARGB(255, 255, 0, 255);
void *DetourFunc(BYTE *src, const BYTE *dst, const int len)
{
BYTE *jmp = (BYTE*)malloc(len + 5);
DWORD dwback;
VirtualProtect(src, len, PAGE_READWRITE, &dwback);
memcpy(jmp, src, len); jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
src[0] = 0xE9;
*(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
VirtualProtect(src, len, dwback, &dwback);
return (jmp - len);
}
bool bDataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for (; *szMask; ++szMask, ++pData, ++bMask)
if (*szMask == 'x' && *pData != *bMask)
return false;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE *bMask, char * szMask)
{
for (DWORD i = 0; i < dwLen; i++)
if (bDataCompare((BYTE*)(dwAddress + i), bMask, szMask))
return (DWORD)(dwAddress + i);
return 0;
}
void DXGH::DrawRect(LPDIRECT3DDEVICE9 Device_t, int X, int Y, int L, int H,
D3DCOLOR color)
{
D3DRECT rect = { X, Y, X + L, Y + H };
Device_t->Clear(1, &rect, D3DCLEAR_TARGET, color, 0, 0);
}
HRESULT WINAPI DXGH::h_EndScene(LPDIRECT3DDEVICE9 pDevice)
{
DXGameHook.DrawRect(pDevice, 10, 10, 200, 200, txtPink);
MessageBoxA(NULL, "test", "1", MB_OK);
return org_EndScene(pDevice);
}
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
int StartD3DHooks()
{
DWORD D3DPattern, *vTable, DXBase = NULL;
DXBase = (DWORD)LoadLibraryA("d3d9.dll");
while (!DXBase);
{
D3DPattern = FindPattern(DXBase, 0x128000,
(PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86"
,"xx????xx????xx");
}
if (D3DPattern)
{
memcpy(&vTable, (void *)(D3DPattern + 2), 4);
org_EndScene = (EndScene_t)DetourFunc((PBYTE)vTable[ENDSCENE],
(PBYTE)DXGameHook.h_EndScene, 5);
}
return 0;
}
How can i set from openCV the focus of a webcam or any other camera? I would like to find the distance of on object, but I want to write the program, so I need to manually be able to focus, manually meaning from code.
I'm using Logitech webcams (tested C525, C920 and C931e). The key 28 is for setting focus. Note that the focus value should be multiples of 5 (0, 5, 10... 255), otherwise the VideoCapture object would simply not respond.
import cv2
cam = cv2.VideoCapture(0)
focus = 0 # min: 0, max: 255, increment:5
cam.set(28, focus)
You can't set focus from opencv, but windows SDK allows it. Take a look at: http://msdn.microsoft.com/en-us/library/windows/hardware/ff567802(v=vs.85).aspx
I've used setting of minidriver properties for focus control, and it works perfect with logitch 905c and 920c.
I found the code example on my disk, hope it'll be userful:
/*****************************************************************************
* DirectShow Pan/Tilt/Zoom sample for Logitech QuickCam devices
*
* Copyright 2007 (c) Logitech. All Rights Reserved.
*
* This code and information is provided "as is" without warranty of
* any kind, either expressed or implied, including but not limited to
* the implied warranties of merchantability and/or fitness for a
* particular purpose.
*
* Version: 1.1
****************************************************************************/
#include <dshow.h>
#include <Ks.h> // Required by KsMedia.h
#include <KsMedia.h> // For KSPROPERTY_CAMERACONTROL_FLAGS_*
struct ControlInfo {
long min;
long max;
long step;
long def;
long flags;
};
/*
* Print information about a control in an easily readable fashion.
*/
void print_control_info(ControlInfo *info)
{
char flags[32] = "";
if(info->flags & KSPROPERTY_CAMERACONTROL_FLAGS_AUTO)
{
strcat_s(flags, sizeof(flags), "AUTO | ");
}
else if(info->flags & KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL)
{
strcat_s(flags, sizeof(flags), "MANUAL | ");
}
if(info->flags & KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE)
{
strcat_s(flags, sizeof(flags), "RELATIVE");
}
else
{
strcat_s(flags, sizeof(flags), "ABSOLUTE");
}
printf(
" min: %d\n"
" max: %d\n"
" step: %d\n"
" def: %d\n"
" flags: 0x%08X (%s)\n",
info->min, info->max, info->step, info->def, info->flags, flags
);
}
/*
* Pans the camera by a given angle.
*
* The angle is given in degrees, positive values are clockwise rotation (seen from the top),
* negative values are counter-clockwise rotation. If the "Mirror horizontal" option is
* enabled, the panning sense is reversed.
*/
HRESULT set_mechanical_pan_relative(IAMCameraControl *pCameraControl, long value)
{
HRESULT hr = 0;
long flags = KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE | KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
hr = pCameraControl->Set(CameraControl_Pan, value, flags);
if(hr != S_OK)
fprintf(stderr, "ERROR: Unable to set CameraControl_Pan property value to %d. (Error 0x%08X)\n", value, hr);
// Note that we need to wait until the movement is complete, otherwise the next request will
// fail with hr == 0x800700AA == HRESULT_FROM_WIN32(ERROR_BUSY).
Sleep(500);
return hr;
}
/*
* Tilts the camera by a given angle.
*
* The angle is given in degrees, positive values are downwards, negative values are upwards.
* If the "Mirror vertical" option is enabled, the tilting sense is reversed.
*/
HRESULT set_mechanical_tilt_relative(IAMCameraControl *pCameraControl, long value)
{
HRESULT hr = 0;
long flags = KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE | KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
hr = pCameraControl->Set(CameraControl_Tilt, value, flags);
if(hr != S_OK)
fprintf(stderr, "ERROR: Unable to set CameraControl_Tilt property value to %d. (Error 0x%08X)\n", value, hr);
// Note that we need to wait until the movement is complete, otherwise the next request will
// fail with hr == 0x800700AA == HRESULT_FROM_WIN32(ERROR_BUSY).
Sleep(500);
return hr;
}
/*
* Resets the camera's pan/tilt position by moving into a corner and then back to the center.
*/
void reset_machanical_pan_tilt(IAMCameraControl *pCameraControl)
{
set_mechanical_pan_relative(pCameraControl, 180);
Sleep(500);
set_mechanical_tilt_relative(pCameraControl, 180);
Sleep(500);
set_mechanical_pan_relative(pCameraControl, -64);
Sleep(500);
set_mechanical_tilt_relative(pCameraControl, -24);
Sleep(500);
}
/*
* Sets the digital pan angle.
*
* Positive values pan to the right, negative values pan to the left. Note that the digital pan
* angle only has an influence if the digital zoom is active.
*/
HRESULT set_digital_pan_absolute(IAMCameraControl *pCameraControl, long value)
{
HRESULT hr = 0;
// Specifying the KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE flag instructs the driver
// to use digital instead of mechanical pan.
long flags = KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE | KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
hr = pCameraControl->Set(CameraControl_Pan, value, flags);
if(hr != S_OK)
fprintf(stderr, "ERROR: Unable to set CameraControl_Pan property value to %d. (Error 0x%08X)\n", value, hr);
return hr;
}
/*
* Sets the digital tilt angle.
*
* Positive values tilt downwards, negative values tilt upwards. Note that the digital pan
* angle only has an influence if the digital zoom is active.
*/
HRESULT set_digital_tilt_absolute(IAMCameraControl *pCameraControl, long value)
{
HRESULT hr = 0;
// Specifying the KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE flag instructs the driver
// to use digital instead of mechanical tilt.
long flags = KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE | KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
hr = pCameraControl->Set(CameraControl_Tilt, value, flags);
if(hr != S_OK)
fprintf(stderr, "ERROR: Unable to set CameraControl_Tilt property value to %d. (Error 0x%08X)\n", value, hr);
return hr;
}
/*
* Sets the digital zoom value.
*
* The minimum value is 50 and means no zoom (100%). The maximum value is 200
* and means 4x zoom (400%).
*/
HRESULT set_digital_zoom_absolute(IAMCameraControl *pCameraControl, long value)
{
HRESULT hr = 0;
long flags = KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE | KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
hr = pCameraControl->Set(CameraControl_Zoom, value, flags);
if(hr != S_OK)
fprintf(stderr, "ERROR: Unable to set CameraControl_Zoom property value to %d. (Error 0x%08X)\n", value, hr);
return hr;
}
/*
* Resets the digital pan and tilt angles.
*/
void reset_digital_pan_tilt(IAMCameraControl *pCameraControl)
{
set_digital_pan_absolute(pCameraControl, 0);
set_digital_tilt_absolute(pCameraControl, 0);
}
/*
* Resets the digital zoom.
*/
void reset_digital_zoom(IAMCameraControl *pCameraControl)
{
set_digital_zoom_absolute(pCameraControl, 50);
}
/*
* Test a camera's pan/tilt properties
*
* See also:
*
* IAMCameraControl Interface
* http://msdn2.microsoft.com/en-us/library/ms783833.aspx
* PROPSETID_VIDCAP_CAMERACONTROL
* http://msdn2.microsoft.com/en-us/library/aa510754.aspx
*/
HRESULT test_pan_tilt(IBaseFilter *pBaseFilter)
{
HRESULT hr = 0;
IAMCameraControl *pCameraControl = NULL;
ControlInfo panInfo = { 0 };
ControlInfo tiltInfo = { 0 };
ControlInfo zoomInfo = { 0 };
long value = 0, flags = 0;
printf(" Reading pan/tilt property information ...\n");
// Get a pointer to the IAMCameraControl interface used to control the camera
hr = pBaseFilter->QueryInterface(IID_IAMCameraControl, (void **)&pCameraControl);
if(hr != S_OK)
{
fprintf(stderr, "ERROR: Unable to access IAMCameraControl interface.\n");
return hr;
}
// Retrieve information about the pan and tilt controls
hr = pCameraControl->GetRange(CameraControl_Pan, &panInfo.min, &panInfo.max, &panInfo.step, &panInfo.def, &panInfo.flags);
if(hr != S_OK)
{
fprintf(stderr, "ERROR: Unable to retrieve CameraControl_Pan property information.\n");
return hr;
}
printf(" Pan control:\n");
print_control_info(&panInfo);
hr = pCameraControl->GetRange(CameraControl_Tilt, &tiltInfo.min, &tiltInfo.max, &tiltInfo.step, &tiltInfo.def, &tiltInfo.flags);
if(hr != S_OK)
{
fprintf(stderr, "ERROR: Unable to retrieve CameraControl_Tilt property information.\n");
return hr;
}
printf(" Tilt control:\n");
print_control_info(&tiltInfo);
hr = pCameraControl->GetRange(CameraControl_Zoom, &zoomInfo.min, &zoomInfo.max, &zoomInfo.step, &zoomInfo.def, &zoomInfo.flags);
if(hr != S_OK)
{
fprintf(stderr, "ERROR: Unable to retrieve CameraControl_Zoom property information.\n");
return hr;
}
printf(" Zoom control:\n");
print_control_info(&zoomInfo);
//*
printf(" Resetting pan/tilt/zoom ...\n");
reset_machanical_pan_tilt(pCameraControl);
reset_digital_pan_tilt(pCameraControl);
reset_digital_zoom(pCameraControl);
Sleep(3000);
//*/
//*
printf(" Testing mechanical pan ...\n");
set_mechanical_pan_relative(pCameraControl, 40);
set_mechanical_pan_relative(pCameraControl, 20);
set_mechanical_pan_relative(pCameraControl, -20);
set_mechanical_pan_relative(pCameraControl, -40);
Sleep(3000);
//*/
//*
printf(" Testing mechanical tilt ...\n");
set_mechanical_tilt_relative(pCameraControl, 20);
set_mechanical_tilt_relative(pCameraControl, 10);
set_mechanical_tilt_relative(pCameraControl, -10);
set_mechanical_tilt_relative(pCameraControl, -20);
Sleep(3000);
//*/
//*
printf(" Testing digital pan/tilt/zoom ...\n");
set_digital_zoom_absolute(pCameraControl, 100); // Zoom to 200%
Sleep(1000);
set_digital_pan_absolute(pCameraControl, 40);
Sleep(1000);
set_digital_pan_absolute(pCameraControl, 80);
Sleep(1000);
set_digital_zoom_absolute(pCameraControl, 200); // Zoom to 400%
Sleep(1000);
set_digital_tilt_absolute(pCameraControl, 40);
Sleep(1000);
set_digital_tilt_absolute(pCameraControl, 60);
Sleep(1000);
reset_digital_pan_tilt(pCameraControl);
Sleep(1000);
reset_digital_zoom(pCameraControl);
Sleep(3000);
//*/
//*
printf(" Testing digital zoom ...\n");
for(int i = zoomInfo.min; i <= zoomInfo.max; i += zoomInfo.step)
{
set_digital_zoom_absolute(pCameraControl, i);
Sleep(10);
}
Sleep(1000);
for(int i = zoomInfo.max; i >= zoomInfo.min; i -= zoomInfo.step)
{
set_digital_zoom_absolute(pCameraControl, i);
Sleep(10);
}
//*/
return S_OK;
}
/*
* Do something with the filter. In this sample we just test the pan/tilt properties.
*/
void process_filter(IBaseFilter *pBaseFilter)
{
test_pan_tilt(pBaseFilter);
}
/*
* Enumerate all video devices
*
* See also:
*
* Using the System Device Enumerator:
* http://msdn2.microsoft.com/en-us/library/ms787871.aspx
*/
int enum_devices()
{
HRESULT hr;
printf("Enumerating video input devices ...\n");
// Create the System Device Enumerator.
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if(FAILED(hr))
{
fprintf(stderr, "ERROR: Unable to create system device enumerator.\n");
return hr;
}
// Obtain a class enumerator for the video input device category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
if(hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if(SUCCEEDED(hr))
{
// To retrieve the filter's friendly name, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
// Display the name in your UI somehow.
wprintf(L" Found device: %s\n", varName.bstrVal);
}
VariantClear(&varName);
// To create an instance of the filter, do the following:
IBaseFilter *pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)&pFilter);
process_filter(pFilter);
//Remember to release pFilter later.
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
return 0;
}
int wmain(int argc, wchar_t* argv[])
{
int result;
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
result = enum_devices();
CoUninitialize();
return result;
}
I am trying to write my first DirectX 10 program that displays a triangle. Everything compiles fine, and the render function is called, since the background changes to black. However, the triangle I'm trying to draw with a triangle strip primitive is not displayed at all.
The Initialization function:
bool InitDirect3D(HWND hWnd, int width, int height)
{
//****** D3DDevice and SwapChain *****//
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = TRUE;
if (FAILED(D3D10CreateDeviceAndSwapChain( NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice)))
return fatalError(TEXT("Hardware does not support DirectX 10!"));
//***** Shader *****//
if (FAILED(D3DX10CreateEffectFromFile( TEXT("basicEffect.fx"),
NULL, NULL,
"fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS,
0,
pD3DDevice,
NULL,
NULL,
&pBasicEffect,
NULL,
NULL)))
return fatalError(TEXT("Could not load effect file!"));
pBasicTechnique = pBasicEffect->GetTechniqueByName("Render");
pViewMatrixEffectVariable = pBasicEffect->GetVariableByName( "View" )->AsMatrix();
pProjectionMatrixEffectVariable = pBasicEffect->GetVariableByName( "Projection" )->AsMatrix();
pWorldMatrixEffectVariable = pBasicEffect->GetVariableByName( "World" )->AsMatrix();
//***** Input Assembly Stage *****//
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}
};
UINT numElements = 2;
D3D10_PASS_DESC PassDesc;
pBasicTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
if (FAILED( pD3DDevice->CreateInputLayout( layout,
numElements,
PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize,
&pVertexLayout)))
return fatalError(TEXT("Could not create Input Layout."));
pD3DDevice->IASetInputLayout( pVertexLayout );
//***** Vertex buffer *****//
UINT numVertices = 100;
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(vertex) * numVertices;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
if (FAILED(pD3DDevice->CreateBuffer(&bd, NULL, &pVertexBuffer)))
return fatalError(TEXT("Could not create vertex buffer!"));;
UINT stride = sizeof(vertex);
UINT offset = 0;
pD3DDevice->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );
//***** Rasterizer *****//
// Set the viewport
viewPort.Width = width;
viewPort.Height = height;
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
pD3DDevice->RSSetViewports(1, &viewPort);
D3D10_RASTERIZER_DESC rasterizerState;
rasterizerState.CullMode = D3D10_CULL_NONE;
rasterizerState.FillMode = D3D10_FILL_SOLID;
rasterizerState.FrontCounterClockwise = true;
rasterizerState.DepthBias = false;
rasterizerState.DepthBiasClamp = 0;
rasterizerState.SlopeScaledDepthBias = 0;
rasterizerState.DepthClipEnable = true;
rasterizerState.ScissorEnable = false;
rasterizerState.MultisampleEnable = false;
rasterizerState.AntialiasedLineEnable = true;
ID3D10RasterizerState* pRS;
pD3DDevice->CreateRasterizerState(&rasterizerState, &pRS);
pD3DDevice->RSSetState(pRS);
//***** Output Merger *****//
// Get the back buffer from the swapchain
ID3D10Texture2D *pBackBuffer;
if (FAILED(pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer)))
return fatalError(TEXT("Could not get back buffer."));
// create the render target view
if (FAILED(pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView)))
return fatalError(TEXT("Could not create the render target view."));
// release the back buffer
pBackBuffer->Release();
// set the render target
pD3DDevice->OMSetRenderTargets(1, &pRenderTargetView, NULL);
return true;
}
The render function:
void Render()
{
if (pD3DDevice != NULL)
{
pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
//create world matrix
static float r;
D3DXMATRIX w;
D3DXMatrixIdentity(&w);
D3DXMatrixRotationY(&w, r);
r += 0.001f;
//set effect matrices
pWorldMatrixEffectVariable->SetMatrix(w);
pViewMatrixEffectVariable->SetMatrix(viewMatrix);
pProjectionMatrixEffectVariable->SetMatrix(projectionMatrix);
//fill vertex buffer with vertices
UINT numVertices = 3;
vertex* v = NULL;
//lock vertex buffer for CPU use
pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v );
v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1) );
v[1] = vertex( D3DXVECTOR3(0,1,0), D3DXVECTOR4(0,1,0,1) );
v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1) );
pVertexBuffer->Unmap();
// Set primitive topology
pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
//get technique desc
D3D10_TECHNIQUE_DESC techDesc;
pBasicTechnique->GetDesc(&techDesc);
for(UINT p = 0; p < techDesc.Passes; ++p)
{
//apply technique
pBasicTechnique->GetPassByIndex(p)->Apply(0);
//draw
pD3DDevice->Draw(numVertices, 0);
}
pSwapChain->Present(0,0);
}
}
I'm not sure try to set:
pD3DDevice->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );
after you unmap the the buffer. To get something like this:
pVertexBuffer->Unmap();
pD3DDevice->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );
// Set primitive topology
pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
I suspect that locking blows avay buffer binding