why openvr GetPoseActionDataForNextFrame is not getting position of controllers - c++

I'm trying to create simple application using OpenVR and OpenGL. Headset tracking and rendering is working, but I'm not getting position of controllers.
Example code from here https://github.com/ValveSoftware/openvr/wiki/API-Documentation works, and is reading my controllers fine.
I'm using json file copied from that example.
Here is simplified version of my code:
vr::IVRSystem* vrSystem= vr::VR_Init( &eError, vr::VRApplication_Scene );
vrSystem->GetRecommendedRenderTargetSize( &vrScreenWidth, &vrScreenHeight );
initWinapi();
initOpenGL();
gladLoadGL();
createTexturesForVrRendering(vrScreenWidth,vrScreenHeight);
vrProjection[vr::Eye_Left] = ConvertSteamVRMatrix44ToMatrix4( vrSystem->GetProjectionMatrix( vr::Eye_Left , 0.001, 100.0 ) );
vrProjection[vr::Eye_Right]= ConvertSteamVRMatrix44ToMatrix4( vrSystem->GetProjectionMatrix( vr::Eye_Right, 0.001, 100.0 ) );
vrEyeTransform[vr::Eye_Left] = ConvertSteamVRMatrix34ToMatrix4( vrSystem->GetEyeToHeadTransform( vr::Eye_Left ) );
vrEyeTransform[vr::Eye_Left].invert();
vrEyeTransform[vr::Eye_Right]= ConvertSteamVRMatrix34ToMatrix4( vrSystem->GetEyeToHeadTransform( vr::Eye_Right ) );
vrEyeTransform[vr::Eye_Right].invert();
compileShaders();
vr::VRCompositor();
vr::VRActionSetHandle_t actionsetDemo = vr::k_ulInvalidActionSetHandle;
vr::VRActionHandle_t handLeftPositionAction = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t handRightPositionAction = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t m_actionHideCubes= vr::k_ulInvalidActionHandle;
vr::VRInput()->SetActionManifestPath( "C:\\src\\helloWorldVr\\openvr_actions.json" );
vr::VRInput()->GetActionHandle( "/actions/demo/in/HideCubes", &m_actionHideCubes );
vr::VRInput()->GetActionSetHandle( "/actions/demo", &actionsetDemo );
vr::VRInput()->GetActionHandle( "/actions/demo/in/Hand_Left", &handLeftPositionAction );
vr::VRInput()->GetActionHandle( "/actions/demo/in/Hand_Right", &handRightPositionAction );
while( appStillRunning ){
static vr::TrackedDevicePose_t m_rTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
vr::VRCompositor()->WaitGetPoses( m_rTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0 );
if( m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid ){
vrHeadPosInv = Matrix4(
m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[0][0], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[1][0], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[2][0], 0.0,
m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[0][1], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[1][1], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[2][1], 0.0,
m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[0][2], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[1][2], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[2][2], 0.0,
m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[0][3], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[1][3], m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking.m[2][3], 1.0f
);
vrHeadPosInv.invert();
}
while( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ){
TranslateMessage( &msg );
DispatchMessage( &msg );
}
vr::VREvent_t event;
while( vrSystem->PollNextEvent( &event, sizeof( event ) ) ){}
vr::VRActiveActionSet_t actionSet = { 0 };
actionSet.ulActionSet = actionsetDemo;
vr::VRInput()->UpdateActionState( &actionSet, sizeof( actionSet ), 1 );
vr::InputPoseActionData_t poseData;
vr::EVRInputError res = vr::VRInput()->GetPoseActionDataForNextFrame( handLeftPositionAction, vr::TrackingUniverseStanding, &poseData, sizeof( poseData ), vr::k_ulInvalidInputValueHandle );
if( res == vr::VRInputError_None ){
if( poseData.bActive && poseData.pose.bPoseIsValid ){ /// poseData.bActive is always false
vrHandPos[vr::Eye_Left]= vrHmdMatrix34_t2Matrix4( poseData.pose.mDeviceToAbsoluteTracking );
}
}
res = vr::VRInput()->GetPoseActionDataForNextFrame( handRightPositionAction, vr::TrackingUniverseStanding, &poseData, sizeof( poseData ), vr::k_ulInvalidInputValueHandle );
if( res == vr::VRInputError_None ){
if( poseData.bActive && poseData.pose.bPoseIsValid ){ /// poseData.bActive is always false
vrHandPos[vr::Eye_Right] = vrHmdMatrix34_t2Matrix4( poseData.pose.mDeviceToAbsoluteTracking );
}
}
renderScene();
vr::Texture_t leftEyeTexture = { (void*)(uintptr_t)vrScreenTexture[0], vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
vr::VRCompositor()->Submit( vr::Eye_Left, &leftEyeTexture );
vr::Texture_t rightEyeTexture = { (void*)(uintptr_t)vrScreenTexture[1], vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
vr::VRCompositor()->Submit( vr::Eye_Right, &rightEyeTexture );
glFinish();
SwapBuffers( hdc );
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glFlush();
glFinish();
}
vr::VR_Shutdown();
shutDownOpenGL();
Am I missing something ?

Related

Crash in DuplicateOutput

I'm developing an application which captures frames using DXGI mechanism from an application.
First creation of the IDXGIOutputDuplication is correct. When the application changes its display (for example from fullscreen to windowed or vice versa), the frame acquire failed (expected behaviour), then I recreate the IDXGIOutputDuplication and regularly the call to DuplicateOutput crash.
Below creation of the D3d11 device:
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
UINT NumFeatureLevels = ARRAYSIZE( FeatureLevels );
D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_1;
D3D11CreateDevice( _pDxgiAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, FeatureLevels, NumFeatureLevels, D3D11_SDK_VERSION, &_pD3D11Device, &FeatureLevel, &_pD3D11DeviceCtx );
_pDxgiAdapter is created before the device.
Below creation of the IDXGIOutputDuplication:
int DxgiVideoCapture::open() {
findDxgiAdapter();
if( nullptr != _pDxgiAdapter ) {
// Duplicate output
uint32_t ui32OutputIndex = 0;
HRESULT hr = S_OK;
while( SUCCEEDED( hr ) ) {
IDXGIOutput* pDxgiOutput = nullptr;
hr = _pDxgiAdapter->EnumOutputs( ui32OutputIndex, &pDxgiOutput );
if( SUCCEEDED( hr ) ) {
IDXGIOutput1* pDxgiOutput1 = nullptr;
if( SUCCEEDED ( pDxgiOutput->QueryInterface( __uuidof( IDXGIOutput1 ), ( void** )&pDxgiOutput1 ) ) ) {
uint32_t ui32EnumMode = 0;
uint32_t ui32Flags = 0xffffffff;
}
if( SUCCEEDED ( pDxgiOutput->QueryInterface( __uuidof( IDXGIOutput1 ), ( void** )&_pDxgiOutput1 ) ) ) {
LOGI( "/!\\ Call which crash regularly /!\\" );
HRESULT hrDup = _pDxgiOutput1->DuplicateOutput( _pD3D11Device, &_pOutputDuplication );
if( SUCCEEDED( hrDup ) ) {
LOGI( "Output duplication created." );
} else {
switch( hrDup ) {
case E_INVALIDARG :
{
LOGW( "Invalid device or output already duplicated" );
}
break;
case E_ACCESSDENIED :
{
LOGW( "Access denied" );
}
break;
case DXGI_ERROR_UNSUPPORTED :
{
LOGW( "DXGI_ERROR_UNSUPPORTED" );
}
break;
case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE :
{
LOGW( "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE" );
}
break;
case DXGI_ERROR_SESSION_DISCONNECTED :
{
LOGW( "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE" );
}
break;
default:
{
LOGW( "default" );
}
}
} else {
LOGE( "Unable to retrieve interface creating the ouput duplication" );
}
}
pDxgiOutput->Release();
}
ui32OutputIndex++;
}
return RET_OK;
}
Below the frame acquisition:
int DxgiVideoCapture::captureGameFrame() {
int iRet = RET_ERROR;
ID3D11Texture2D* pCapturedTexture = nullptr;
DXGI_OUTDUPL_FRAME_INFO frameInfo;
ZeroMemory(&frameInfo, sizeof(frameInfo));
HRESULT hr = _pOutputDuplication->AcquireNextFrame( 1000, &frameInfo, &_pDxgiResource );
if( FAILED( hr ) ) {
if( hr == DXGI_ERROR_WAIT_TIMEOUT ) {
LOGW( "Wait for %d ms timed out", 1000);
}
if (hr == DXGI_ERROR_INVALID_CALL) {
LOGW( "Invalid Call, previous frame not released?" );
}
if (hr == DXGI_ERROR_ACCESS_LOST) {
LOGW( "Error Access lost - is it a game end ?" );
}
iRet = RET_RESET_CAPTURE;
return iRet;
}
if( FAILED( hr = _pDxgiResource->QueryInterface( __uuidof( ID3D11Texture2D ), ( void** ) &pCapturedTexture ) ) ) {
LOGW( "unable to retrieve D3D11 texture 0x%x", hr );
return RET_WARNING;
} else {
// Store window of the game
D3D11_TEXTURE2D_DESC d3D11TextureDesc;
pCapturedTexture->GetDesc( &d3D11TextureDesc );
// Compute the zone to extract.
D3D11_BOX srcBox;
memset( &srcBox, 0, sizeof( srcBox ) );
if( _pGameWindow->getLeftPos() > 0 ) {
srcBox.left = _pGameWindow->getLeftPos();
}
if( _pGameWindow->getTopPos() > 0 ) {
srcBox.top = _pGameWindow->getTopPos();
}
srcBox.front = 0;
srcBox.right = _pGameWindow->getLeftPos() + _pGameWindow->getWidth();
if( srcBox.right > _pGameWindow->getMonitorWidth() ) {
srcBox.right = _pGameWindow->getMonitorWidth();
}
if( ( srcBox.right - srcBox.left ) % 2 != 0 ) {
srcBox.right--;
}
srcBox.bottom = _pGameWindow->getTopPos() + _pGameWindow->getHeight();
if( srcBox.bottom > _pGameWindow->getMonitorHeight() ) {
srcBox.bottom = _pGameWindow->getMonitorHeight();
}
if( ( srcBox.bottom - srcBox.top ) % 2 != 0 ) {
srcBox.bottom--;
}
srcBox.back = 1;
// AVFrame info are udpate just when the captured game window and the texture are diffrent.
// In the same time texture is reallocated.
if( ( ( srcBox.right - srcBox.left ) != _CapturedTextureDesc.Width )
|| ( ( srcBox.bottom - srcBox.top ) != _CapturedTextureDesc.Height )
) {
LOGD( "Game window: %dx%d ; %d->%d", _pGameWindow->getLeftPos(), _pGameWindow->getTopPos(), _pGameWindow->getWidth(), _pGameWindow->getHeight() );
LOGD( "Texture creation %dx%d -> %dx%d", srcBox.left, srcBox.top, srcBox.right, srcBox.bottom );
// Create the new texture
iRet = createCapturedTexture( srcBox.right - srcBox.left, srcBox.bottom - srcBox.top );
}
DirectX11Util::GetInstance()->getD3D11DeviceContext()->CopySubresourceRegion( _pGameTexture, 0, 0, 0, 0, pCapturedTexture, 0, &srcBox );
}
if( nullptr != _pDxgiResource ) {
_pOutputDuplication->ReleaseFrame();
pCapturedTexture->Release();
_pDxgiResource->Release();
_pDxgiResource = nullptr;
}
iRet = RET_OK;
return iRet;
}
Below the release of the D3d11 capture before recreation of the IDXGIOutputDuplication:
int DxgiVideoCapture::close() {
if( nullptr != _pGameTexture ) {
ZeroMemory( &_CapturedTextureDesc, sizeof( D3D11_TEXTURE2D_DESC ) );
_pGameTexture->Release();
_pGameTexture = nullptr;
}
if( nullptr != _pDxgiResource ){
_pOutputDuplication->ReleaseFrame();
_pDxgiResource->Release();
_pDxgiResource = nullptr;
}
if( nullptr != _pOutputDuplication ) {
_pOutputDuplication->Release();
_pOutputDuplication = nullptr;
}
return RET_OK;
}
What I would like to know is how can I invest this crash (application ends without any message). To be more accurate I cross compile my application, but the behaviour seems the same. Do you have any idea how to invest this issue ?
Tell me if you want more details.
Thanks in advance !

Creating Seperate Context for Each GPU while having one display monitor

I want to create one GL Context for each GPU on Linux using the GLX. As nVIDIA Slides show, it is pretty simple and I just have to use ":0.0" for the first gpu and ":0.1" for the second one in XOpenDisplay function. I have tried it but it only works with ":0.0" but not with ":0.1". I have two gpus: GTX 980 and GTX 970. Also, as the xorg.conf shows the Xinerama is disabled. Furthermore, I only have one display monitor and it is connected to the GTX 980.
Do you have any idea about how to fix that? or what is missing?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glx.h>
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
// Helper to check for extension string presence. Adapted from:
// http://www.opengl.org/resources/features/OGLextensions/
static bool isExtensionSupported(const char *extList, const char *extension)
{
const char *start;
const char *where, *terminator;
/* Extension names should not have spaces. */
where = strchr(extension, ' ');
if (where || *extension == '\0')
return false;
/* It takes a bit of care to be fool-proof about parsing the
OpenGL extensions string. Don't be fooled by sub-strings,
etc. */
for (start=extList;;) {
where = strstr(start, extension);
if (!where)
break;
terminator = where + strlen(extension);
if ( where == start || *(where - 1) == ' ' )
if ( *terminator == ' ' || *terminator == '\0' )
return true;
start = terminator;
}
return false;
}
static bool ctxErrorOccurred = false;
static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
{
ctxErrorOccurred = true;
return 0;
}
int main(int argc, char* argv[])
{
Display *display = XOpenDisplay(":0.1");
if (!display)
{
printf("Failed to open X display\n");
exit(1);
}
// Get a matching FB config
static int visual_attribs[] =
{
GLX_X_RENDERABLE , True,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
GLX_RENDER_TYPE , GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_ALPHA_SIZE , 8,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
//GLX_SAMPLE_BUFFERS , 1,
//GLX_SAMPLES , 4,
None
};
int glx_major, glx_minor;
// FBConfigs were added in GLX version 1.3.
if ( !glXQueryVersion( display, &glx_major, &glx_minor ) ||
( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
{
printf("Invalid GLX version");
exit(1);
}
printf( "Getting matching framebuffer configs\n" );
int fbcount;
GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);
if (!fbc)
{
printf( "Failed to retrieve a framebuffer config\n" );
exit(1);
}
printf( "Found %d matching FB configs.\n", fbcount );
// Pick the FB config/visual with the most samples per pixel
printf( "Getting XVisualInfos\n" );
int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
int i;
for (i=0; i<fbcount; ++i)
{
XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] );
if ( vi )
{
int samp_buf, samples;
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples );
printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
" SAMPLES = %d\n",
i, vi -> visualid, samp_buf, samples );
if ( best_fbc < 0 || samp_buf && samples > best_num_samp )
best_fbc = i, best_num_samp = samples;
if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
worst_fbc = i, worst_num_samp = samples;
}
XFree( vi );
}
GLXFBConfig bestFbc = fbc[ best_fbc ];
// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
XFree( fbc );
// Get a visual
XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
printf( "Chosen visual ID = 0x%x\n", vi->visualid );
printf( "Creating colormap\n" );
XSetWindowAttributes swa;
Colormap cmap;
swa.colormap = cmap = XCreateColormap( display,
RootWindow( display, vi->screen ),
vi->visual, AllocNone );
swa.background_pixmap = None ;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
printf( "Creating window\n" );
Window win = XCreateWindow( display, RootWindow( display, vi->screen ),
0, 0, 100, 100, 0, vi->depth, InputOutput,
vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa );
if ( !win )
{
printf( "Failed to create window.\n" );
exit(1);
}
// Done with the visual info data
XFree( vi );
XStoreName( display, win, "GL 3.0 Window" );
printf( "Mapping window\n" );
XMapWindow( display, win );
// Get the default screen's GLX extension list
const char *glxExts = glXQueryExtensionsString( display,
DefaultScreen( display ) );
// NOTE: It is not necessary to create or make current to a context before
// calling glXGetProcAddressARB
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
GLXContext ctx = 0;
// Install an X error handler so the application won't exit if GL 3.0
// context allocation fails.
//
// Note this error handler is global. All display connections in all threads
// of a process use the same error handler, so be sure to guard against other
// threads issuing X commands while this code is running.
ctxErrorOccurred = false;
int (*oldHandler)(Display*, XErrorEvent*) =
XSetErrorHandler(&ctxErrorHandler);
// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
!glXCreateContextAttribsARB )
{
printf( "glXCreateContextAttribsARB() not found"
" ... using old-style GLX context\n" );
ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True );
}
// If it does, try to get a GL 3.0 context!
else
{
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
printf( "Creating context\n" );
ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
True, context_attribs );
// Sync to ensure any errors generated are processed.
XSync( display, False );
if ( !ctxErrorOccurred && ctx )
printf( "Created GL 3.0 context\n" );
else
{
// Couldn't create GL 3.0 context. Fall back to old-style 2.x context.
// When a context version below 3.0 is requested, implementations will
// return the newest context version compatible with OpenGL versions less
// than version 3.0.
// GLX_CONTEXT_MAJOR_VERSION_ARB = 1
context_attribs[1] = 1;
// GLX_CONTEXT_MINOR_VERSION_ARB = 0
context_attribs[3] = 0;
ctxErrorOccurred = false;
printf( "Failed to create GL 3.0 context"
" ... using old-style GLX context\n" );
ctx = glXCreateContextAttribsARB( display, bestFbc, 0,
True, context_attribs );
}
}
// Sync to ensure any errors generated are processed.
XSync( display, False );
// Restore the original error handler
XSetErrorHandler( oldHandler );
if ( ctxErrorOccurred || !ctx )
{
printf( "Failed to create an OpenGL context\n" );
exit(1);
}
// Verifying that context is a direct context
if ( ! glXIsDirect ( display, ctx ) )
{
printf( "Indirect GLX rendering context obtained\n" );
}
else
{
printf( "Direct GLX rendering context obtained\n" );
}
printf( "Making context current\n" );
glXMakeCurrent( display, win, ctx );
glClearColor( 0, 0.5, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glXSwapBuffers ( display, win );
sleep( 1 );
glClearColor ( 1, 0.5, 0, 1 );
glClear ( GL_COLOR_BUFFER_BIT );
glXSwapBuffers ( display, win );
sleep( 1 );
glXMakeCurrent( display, 0, 0 );
glXDestroyContext( display, ctx );
XDestroyWindow( display, win );
XFreeColormap( display, cmap );
XCloseDisplay( display );
return 0;
}
The reason it works with ":0.0" but not with ":0.1" is because they are the X display and screen numbers. ":0.0" means the first screen on the first display and ":0.1" means the second screen on the first display.
These numbers are for selecting which monitor you wish to display the window to and not which GPU you wish to use. As you have only one monitor attached you only have one screen so ":0.1" fails.
I believe the slides expect you to have two or more monitors attached, each driven by a different GPU.

Loading bitmap image to button

I am working on legacy application, i added a button(Switch/pushlike) to a dialog i want to add bitmap image to that, to get the reference there is getdlgitem(id) but here this function is also demanding hwnd object,
on searching the code i found previously they used following three functions
environ_control->dialwindow
environ_get_active_dialogue()
environ_get_ActiveWindow()
to pass in the place of hwnd, none of them is working for me,
i tried it like this
CButton* pButton = (CButton*)GetDlgItem(environ_get_active_dialogue(),IDD_BTN_CUSTOMRANDC );
pButton->SetBitmap((HBITMAP)Bmp1);
It gives debug assertion failed on second line, any help please, the function code is
SYMBOLIC JOB_PSNUP::nup_init_nup_dialog( void )
{
int arrTabs[8];
arrTabs[0] = 6;
arrTabs[1] = 28;
arrTabs[2] = 61;
arrTabs[3] = 97;
arrTabs[4] = 137;
arrTabs[5] = 179;
arrTabs[6] = 218;
// Reset information about Preview area
m_hwndPreview = NULL;
m_hdcPreview = NULL;
m_rFront.top = m_rFront.bottom = m_rFront.left = m_rFront.right = 0;
m_rBack.top = m_rBack.bottom = m_rBack.left = m_rBack.right = 0;
CBitmap Bmp1, Bmp2;
m_bSetOrderMode = FALSE;
m_iCurrOrder = 1;
environ_set_dlg_item_text_win( IDD_SNAME, "<click on page>" );
CDataExchange dx(CWnd::FromHandle(environ_get_active_dialogue()), FALSE);
ELX_INT BtnIndex;
comm->m_pXPBtn[BtnIndex = comm->GetIndexForNewBtn()] = new ECXPStyleButton;
comm->m_pXPBtn[comm->GetIndexForNewBtn()] = new ECXPStyleButton;
comm->initXPBtn(comm->m_pXPBtn[BtnIndex+0], IDD_NUMOVEUP, &dx, IDB_MOVEUP, "Move up");
comm->initXPBtn(comm->m_pXPBtn[BtnIndex+1], IDD_NUMOVEDOWN, &dx, IDB_MOVEDOWN, "Move down");
ECListCtrl* pListCtrl = comm->InitECListCtrl(IDD_NULIST, _T("Order,70;Side,50;Number,60;H.Offset,60;V.Offset,60;Constant,60;Forms,50"));
pListCtrl->GetHeaderCtrl()->EnableWindow(FALSE);
comm->state.enSortBy2 = SORT_DOC_BY_NAME_ASC;
environ_set_resource_object_state( 0, IDD_NUCURRORDER, OBJECT_STATE_DISABLED, FALSE );
environ_set_resource_object_state( 0, IDD_NUORDERLAB, OBJECT_STATE_DISABLED, FALSE );
environ_message_handler( ENVIRON_LBSET_TAB_STOPS, (void*)IDD_NULIST, (void*)(&arrTabs));
environ_message_handler( ENVIRON_LBSET_HEXTENT, (void*)IDD_NULIST, (void*)(1000) );
comm->dial.dial_stack_fake[0] = '\0';
environ_set_string_into_resource_object( 0, IDD_NUHOFFSET, comm->dial.dial_stack_fake, FALSE );
Bmp1.LoadBitmapA(IDB_BUTTON_ON);
Bmp2.LoadBitmapA(IDB_BUTTON_OFF);
if( environ_is_object_selected( 0, IDD_BTN_CUSTOMRANDC ))
{
CButton* pButton = (CButton*)GetDlgItem(environ_get_active_dialogue(),IDD_BTN_CUSTOMRANDC );
pButton->SetBitmap((HBITMAP)Bmp2);
}
else
{
CButton* pButton = (CButton*)GetDlgItem(environ_get_active_dialogue(),IDD_BTN_CUSTOMRANDC );
pButton->SetBitmap((HBITMAP)Bmp1);
}
// Total number of partitions
environ_set_dlg_item_int_win( IDD_NUTOTNUM, m_iTotal );
// On Back side
if( m_enPaperDuplex == JOB_SIMPLEX )
{
environ_set_resource_object_state( 0, IDD_NUFRONTNUMLAB, OBJECT_STATE_HIDDEN, FALSE );
environ_set_resource_object_state( 0, IDD_NUFRONTNUM, OBJECT_STATE_HIDDEN, FALSE );
environ_set_resource_object_state( 0, IDD_NUBACKNUMLAB, OBJECT_STATE_HIDDEN, FALSE );
environ_set_resource_object_state( 0, IDD_NUBACKNUM, OBJECT_STATE_HIDDEN, FALSE );
environ_set_resource_object_state( 0, IDD_NUFRONTLAB, OBJECT_STATE_HIDDEN, FALSE );
environ_set_resource_object_state( 0, IDD_NUBACKLAB, OBJECT_STATE_HIDDEN, FALSE );
environ_set_dlg_item_text_win( IDD_NUTOTNUMLAB, "&Number of Partitions:" );
}
else
{
environ_set_dlg_item_int_win( IDD_NUFRONTNUM, m_iOnFront );
environ_set_dlg_item_int_win( IDD_NUBACKNUM, m_iOnBack );
}
// Offset units
comm->job_prop->jobprop_get_unit_name( comm->formdef.props.units, FALSE/*TRUE*/, comm->state.workstring ); // SMP
environ_set_dlg_item_text_win( IDD_UNITSTR0, comm->state.workstring );
environ_set_dlg_item_text_win( IDD_UNITSTR1, comm->state.workstring );
if( comm->job_config.flag.auto_offset_paper_partitions )
{
environ_set_resource_object_on_or_off( 0, IDD_NUAUTOOFFSET, TRUE );
}
// List of Partitions
nup_fill_list();
m_NupDialExit = USER_CANCEL;
return( 0 );
}
The version of GetDlgItem that takes two parameters returns an HWND, not a CWnd*. So it is incorrect to cast it to CButton*. Instead, use GetDlgItem(IDD_BTN_CUSTOMRANDC).

Images and text not showing in SDL under Mac OSX

I got to compile, bundle and load resources under XCode 4.3 and SDL 1.2.15
I know resources are loading correctly because file handles are not null and no error is thrown.
I successfully load png's and ttf's, obtain and crop surfaces, and blit them.
But when I flip, the only thing I get to see are the lines I drew using SDL_Draw
I will put some bits of code, as I'm trying to keep an engine-ish structure so the code is everything but together.
Initialization:
void CEngine::Init() {
// Register SDL_Quit to be called at exit; makes sure things are cleaned up when we quit.
atexit( SDL_Quit );
// Initialize SDL's subsystems - in this case, only video.
if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
fprintf( stderr, "Unable to init SDL: %s\n", SDL_GetError() );
exit( 1 );
}
// Attempt to create a window with the specified height and width.
SetSize( m_iWidth, m_iHeight );
// If we fail, return error.
if ( m_pScreen == NULL ) {
fprintf( stderr, "Unable to set up video: %s\n", SDL_GetError() );
exit( 1 );
}
AdditionalInit();
}
and
void CTileEngine::AdditionalInit() {
SetTitle( "TileEngine - Loading..." );
PrintDebug("Initializing SDL_Image");
int flags = IMG_INIT_PNG;
int initted = IMG_Init( flags );
if( ( initted & flags ) != flags ) {
PrintDebug("IMG_Init: Failed to init required image support!");
PrintDebug(IMG_GetError());
// handle error
}
PrintDebug("Initializing SDL_TTF");
if( TTF_Init() == -1 ) {
PrintDebug("TTF_Init: Failed to init required ttf support!");
PrintDebug(TTF_GetError());
}
PrintDebug("Loading fonts");
font = TTF_OpenFont( OSXFileManager::GetResourcePath("Roboto-Regular.ttf"), 28 );
if( !font ) {
PrintDebug("Error loading fonts");
PrintDebug(TTF_GetError());
}
g_pGame = new CGame;
LoadGame( OSXFileManager::GetResourcePath( "test", "tmx") );
SetTitle( "TileEngine" );
PrintDebug("Finished AditionalInit()");
}
Main draw method
void CEngine::DoRender(){
++m_iFPSCounter;
if ( m_iFPSTickCounter >= 1000 ) {
m_iCurrentFPS = m_iFPSCounter;
m_iFPSCounter = 0;
m_iFPSTickCounter = 0;
}
SDL_FillRect( m_pScreen, 0, SDL_MapRGB( m_pScreen->format, 0, 0, 0 ) );
// Lock surface if needed
if ( SDL_MUSTLOCK( m_pScreen ) ){
if ( SDL_LockSurface( m_pScreen ) < 0 ){
return;
}
}
Render( GetSurface() );
// Render FPS
SDL_Color fpsColor = { 255, 255, 255 };
string fpsMessage = "FPS: ";
fpsMessage.append( SSTR(m_iCurrentFPS) );
SDL_Surface* fps = TTF_RenderText_Solid(font, fpsMessage.c_str(), fpsColor);
if( fps ) {
SDL_Rect destRect;
destRect.x = pDestSurface->w - fps->w;
destRect.y = pDestSurface->h - fps->h;
destRect.w = fps->w;
destRect.h = fps->h;
SDL_BlitSurface(fps, &fps->clip_rect, pDestSurface, &destRect);
SDL_FreeSurface(fps);
}
// Unlock if needed
if ( SDL_MUSTLOCK( m_pScreen ) )
SDL_UnlockSurface( m_pScreen );
// Tell SDL to update the whole gScreen
SDL_Flip( m_pScreen );
}
Image file loading
bool CEntity::VLoadImageFromFile( const string& sFile) {
if ( m_pSurface != 0 ){
SDL_FreeSurface( m_pSurface );
}
string nFile = string(OSXFileManager::APPNAME) + OSXFileManager::RESOURCEDIR + sFile;
SDL_Surface *pTempSurface;
pTempSurface = IMG_Load( nFile.c_str() );
m_sImage = sFile;
if ( pTempSurface == 0 ){
char czError[256];
sprintf( czError, "Image '%s' could not be opened. Reason: %s", nFile.c_str(), IMG_GetError() );
fprintf( stderr, "\nERROR: %s", czError );
return false;
} else {
pTempSurface = SDL_DisplayFormatAlpha(pTempSurface);
}
m_pSurface = pTempSurface;
return true;
}
Entity draw method
void CEntity::VRender( SDL_Surface *pDestSurface ) {
if ( ( m_pSurface == 0 ) || ( m_bVisible == false) || ( m_iAlpha == 0 ) ){
// If the surface is invalid or it's 100% transparent.
return;
}
SDL_Rect SDestRect;
SDestRect.x = m_iPosX;
SDestRect.y = m_iPosY;
SDestRect.w = m_pSurface->w;
SDestRect.h = m_pSurface->h;
if ( m_iAlpha != 255 )
SDL_SetAlpha( m_pSurface, SDL_SRCALPHA, m_iAlpha );
SDL_BlitSurface( m_pSurface, &m_pSurface->clip_rect, pDestSurface, &SDestRect );
}
I have checked and debugged million times and I don't get what's wrong here. As I told before, file loading seems to be OK.
But this part
void CTile::RenderGrid( SDL_Surface* pDestSurface ) {
Uint32 m_GridColor = SDL_MapRGB( pDestSurface->format, 0xFF, 0xFF, 0xFF );
Draw_Rect(pDestSurface, GetPosX(), GetPosY(), GetWidth(), GetHeight(), m_GridColor);
}
works like a charm.
I found out what was happening. Turns out that, from SDL version 1.1.18 SDL_Lock calls are recursive, so each lock must pair an unlock. That was not happening last time I used SDL, so I was not aware of it. Simply matching locks and unlocks did the job.

why is this value being set to 0? O_O

chMB() is a define to MessageBoxA( 0, text, "title", MB_OK );so it displays the text and I can see results. My problem is with the following codez:
CString szWow;
szWow.Format( "%u", idCandidate );
chMB( szWow );
const __int64 i64set = i64VoteAmount+1;
CString addvote;
addvote.Format( "UPDATE dbo.CONSULENTRIES set m_uVoteAmount = %u WHERE m_idCandidate = %u", i64set, idCandidate );
chMB( addvote );
chMB( szWow ); displayes 5
althought chMB( addVote ) displayes:
UPDATE dbo.CONSULENTRIES set m_uVoteAmount = 1 WHERE m_idCandidate = 0
why is idCandidate 0 on this string format??? O___O
in case you need here is teh full codez:
VOTEAPPL CConsulApplication::VoteForApplied( const u_long idVoter, const __int64 idCandidate )
{
if( idVoter && idCandidate )
{
/* Check if alredy voted */
CQuery* pQuery = new CQuery;
if( !pQuery->Connect( 3, DSN_NAME_CHARACTER01, DB_ADMIN_ID_CHARACTER01, DB_ADMIN_PASS_CHARACTER01 ) )
{
pQuery->DisConnect();
SAFE_DELETE( pQuery );
return VAPL_FAILURE;
}
CString szVoted;
szVoted.Format( "SELECT * FROM dbo.CONSULVOTE WHERE m_idVoter = %u", idVoter );
if( !pQuery->Exec( szVoted ) )
{
pQuery->DisConnect();
SAFE_DELETE( pQuery );
return VAPL_FAILURE;
}
pQuery->Fetch();
__int64 i64Voter = pQuery->GetInt64( "m_idVoter" );
if( i64Voter != 0 )
{
pQuery->DisConnect();
SAFE_DELETE( pQuery );
return VAPL_VOTED;
}
pQuery->DisConnect();
SAFE_DELETE( pQuery );
/* Get content and check if candidate exists */
CQuery* pQuery2 = new CQuery;
if( !pQuery2->Connect( 3, DSN_NAME_CHARACTER01, DB_ADMIN_ID_CHARACTER01, DB_ADMIN_PASS_CHARACTER01 ) )
{
pQuery2->DisConnect();
SAFE_DELETE( pQuery2 );
return VAPL_FAILURE;
}
CString szCandidate;
szCandidate.Format( "SELECT * FROM dbo.CONSULENTRIES WHERE m_idCandidate = %u", idCandidate );
if( !pQuery2->Exec( szCandidate ) )
{
pQuery2->DisConnect();
SAFE_DELETE( pQuery2 );
return VAPL_FAILURE;
}
pQuery2->Fetch();
__int64 i64Candidate = pQuery2->GetInt64( "m_idCandidate" );
__int64 i64VoteAmount = pQuery2->GetInt64( "m_uVoteAmount" );
if( i64Candidate != 0 )
{
/* Insert at database that this guy has voted */
CQuery* pInsertQuery = new CQuery;
if( !pInsertQuery->Connect( 3, DSN_NAME_CHARACTER01, DB_ADMIN_ID_CHARACTER01, DB_ADMIN_PASS_CHARACTER01 ) )
{
pInsertQuery->DisConnect();
SAFE_DELETE( pInsertQuery );
return VAPL_FAILURE;
}
CString szInsert;
szInsert.Format( "INSERT INTO dbo.CONSULVOTE values(%u,%u)", idVoter, idCandidate );
if( !pInsertQuery->Exec( szInsert ) )
{
pInsertQuery->DisConnect();
SAFE_DELETE( pInsertQuery );
return VAPL_FAILURE;
}
pInsertQuery->DisConnect();
SAFE_DELETE( pInsertQuery );
/* Update vote amount */
CQuery* pUpdate = new CQuery;
if( !pUpdate->Connect( 3, DSN_NAME_CHARACTER01, DB_ADMIN_ID_CHARACTER01, DB_ADMIN_PASS_CHARACTER01 ) )
{
pUpdate->DisConnect();
SAFE_DELETE( pUpdate );
return VAPL_FAILURE;
}
CString szWow;
szWow.Format( "%u", idCandidate );
chMB( szWow );
const __int64 i64set = i64VoteAmount+1;
CString addvote;
addvote.Format( "UPDATE dbo.CONSULENTRIES set m_uVoteAmount = %u WHERE m_idCandidate = %u", i64set, idCandidate );
chMB( addvote );
if( !pUpdate->Exec( addvote ) )
{
pUpdate->DisConnect();
SAFE_DELETE( pUpdate );
return VAPL_FAILURE;
}
pUpdate->DisConnect();
SAFE_DELETE( pUpdate );
return VAPL_SUCCESS;
}
pQuery2->DisConnect();
SAFE_DELETE( pQuery2 );
return VAPL_FAILURE;
}
return VAPL_FAILURE;
}
The problem is here:
addvote.Format( "UPDATE dbo.CONSULENTRIES set m_uVoteAmount = %u WHERE m_idCandidate = %u", i64set, idCandidate );
The format string contains %u while the variable after the format string (i64set) is of a wrong type (__int64).
Try changing the type (%u corresponds to type unsigned int) or the format specifier:
addvote.Format( "UPDATE dbo.CONSULENTRIES set m_uVoteAmount = %I64d WHERE m_idCandidate = %u", i64set, idCandidate );