Understanding Vulkan uniform layout's 'set' index - graphics

I've been following along in the (very awesome) nvpro raytracing tutorial and have a question about the way the CameraProperties uniform buffer is bound using layout(binding = 0, set = 1) - I understand the binding = 0, but why set = 1?
The tutorial says "The set = 1 comes from the fact that it is the second descriptor set passed to pipelineLayoutCreateInfo.setPSetLayouts", but when I look at HelloVulkan::createGraphicsPipeline() I see the layout count is one, and this is where m_descSetLayout (what binds the camera uniform buffer) is used. What am I missing?
The related section of the tutorial is here.
Thanks!

See chapter 7.1:
std::vector<vk::DescriptorSetLayout> rtDescSetLayouts = {m_rtDescSetLayout, m_descSetLayout};
pipelineLayoutCreateInfo.setSetLayoutCount(static_cast<uint32_t>(rtDescSetLayouts.size()));
pipelineLayoutCreateInfo.setPSetLayouts(rtDescSetLayouts.data());
The pipeline layout contains two descriptor set layouts, m_rtDescSetLayout for the acceleration structures at index 0 (set 0) and m_descSetLayout for the screne descriptors in index 1 (set 1). In Vulkan the set is automatically derived from a descriptor set layout's index in the pipeline layouts create info.

Related

Using CMFCMenuButton::SizeToContent does not seem to work as I would like. Why?

I am perplexed about the SizeToContent method of the CMFCMenuButton control.
This is my dialog in the IDE:
As you can see, I have specifically made the button wider than the two on the far right.
I added the following code to OnInitDialog:
// Resize (if required)
const auto sizNewButton = m_btnReset.SizeToContent(true);
CRect rctButton;
m_btnReset.GetWindowRect(&rctButton);
if(sizNewButton.cx > rctButton.Width())
{
m_btnReset.SizeToContent();
}
Yet, when I run my application in English:
It has made it smaller. My application supports 50+ languages by using satellite DLLs and I was hoping to only resize to content if it was required. But it seems to resize it anyway. Have I missed a step here?
I have checked the properties for the control in the IDE and it is not set to auto resize:
I notice that the help documentation states:
The new size of the button is calculated to fit the button text, image, and arrow. The framework also adds in predefined margins of 10 pixels for the horizontal edge and 5 pixels for the vertical edge.
I had a look at my button:
Default size: 48 x 23 (the GeWindowRect result).
Calculated size: 57 x 23 (the SizeToContent result).
If I adjusted my code like this:
if((sizNewButton.cx - 10) > rctButton.Width())
That would bring it down to 47 and thus would not resize. I am assuming the code is not working right because of the padded margin that GetWindowRect knows nothing about.
Searched it, and found that the problem is MFC's CMFCMenuButton::SizeToContent() implementation in afxmenubutton.cpp:
CSize CMFCMenuButton::SizeToContent(BOOL bCalcOnly)
{
CSize size = CMFCButton::SizeToContent(FALSE); // <==== The culprit!!!
size.cx += CMenuImages::Size().cx;
if (!bCalcOnly)
{
SetWindowPos(NULL, -1, -1, size.cx, size.cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
}
return size;
}
That is, it calls the base implementation of SizeToContent() with the bCalcOnly parameter set to FALSE, which means it will also resize the control to just fit the text (without the drop-down arrow). This is less than required for the text plus the arrow, and of course the original size is lost.
A workaround can be get the (original) width, before the SizeToContent() call, and work with this instead of the new one:
CRect rctButton;
m_btnReset.GetWindowRect(&rctButton);
const auto nOrigWidth = rctButton.Width(); // Store the original width
const auto sizNewButton = m_btnReset.SizeToContent(true); // This resizes the control!!!
if (sizNewButton.cx > nOrigWidth) // Compare to the original width rather than the new one
m_btnReset.SizeToContent();
else // Restore original width
m_btnReset.SetWindowPos(NULL, -1, -1, nOrigWidth, sizNewButton.cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
Alternative Workaround:
Define a new CMFCMenuButton-based class, overriding SizeToContent() - in the implementation call the base CMFCButton::SizeToContent() with the bCalcOnly parameter passed by the caller, not with FALSE. Map the control to this class instead of CMFCMenuButton. That is use a class that fixes it. Too much of an overkill for just a workaround though.

Flash CC Canvas and GSAP: How to set registration point of movieclip on stage

How would I go about changing the registration point of a movieclip labeled "tablet" placed on the stage (root) dynamically?
For example: I have the following:
var tablet = this.tablet; //movieclip labeled "tablet" on stage
function resetTablet(){
tablet.regX = tablet.width/2; //move registration point to center
tablet.regY = tablet.height/2;
}
However when I call it using GSAP:
var tl = new TimelineLite();
tl.to(tablet, 1, {alpha:1, onComplete:resetTablet})
.to(tablet, 3, {alpha:0, scaleX:1.5, scaleY:1.5})
the registration point is still set to the upper left corner rather than the center.
What am I doing wrong here? Thanks!
Registration points affect change both the transformation point, but also the position. If you set a displayobject that is 100x100 pixels to regX=50;regY=50, then it will draw from that point, moving the content 50px to the top and left. If you make that change you should also translate the clip to x=50;y=50.
An issue with you example is that there is no width or height on EaselJS content (explained here). You can get the bounds of anything generated by Flash CC using the nominalBounds property, which Flash exports as a property on every object. If you have multiple frames, you can turn on "multi-frame bounds" in the publish settings, and a frameBounds property is added to the objects as well.
Note that nominalBounds and frameBounds are not used by the getBounds method.
Here is how you might be able to approach it.
var bounds = tablet.nominalBounds;
tablet.regX = bounds.width/2;
tablet.regY = bounds.height/2;
// Optional if your actual registration point was [0,0] before:
tablet.x += tablet.regX;
tablet.y += tablet.regX;
Hope that helps.

x11 - how to set _NET_WM_ALLOWED_ACTIONS

I use XCreateSimpleWindow to create x11 window. xprop shows following allowed actions for my window:
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_STICK, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW
What happens if I don't set them explicitly (like above) ? A window has a default list which contains all of them ? How to set them explicitly ?
Edit1
Here is example code which sets only one allowed action:
Atom aa = XInternAtom(d, "_NET_WM_ALLOWED_ACTIONS", False);
Atom close = XInternAtom(d, " _NET_WM_ACTION_CLOSE", False);
XChangeProperty(d, w, aa, XA_ATOM, 32, PropertyNewValue, (unsigned char*)&close, 1);
Window manager still let me move or resize window so maybe I should send some client message ? I want to have a window which allows only for close actions.
1) no, by default window does not have properties, but window managers often set some default values. Try to run your program without WM to see difference
2) use "ChangeProperty" request. Window property is some data associated with window + a little bit of metadata: name (atom) and type (atom). If size of data is more than single type would need it's assumed you have array of those. For example, atom is just 32 bit unsigned int. If you see 8 bytes property of type atom, you interpret content as two atoms. See XChangeProperty documentation if you are using xlib

Detect all available scanner resolutions using WIA

How can I programmatically detect all available resolutions (in dpi) for a specified scanner using WIA 2.0? What about page sizes supported? Any ideas?
Pseudo code:
Assume you have device info, connect to it:
var device = deviceInfo.Connect();
if device is not null….. then you can get the Item
Note that items begin at index 1 for device items
Item item = device.Items[1];
An Item has various properties which you can enumerate
e.g.
foreach (Property prop in item.Properties)
{
var temp = prop.Name + " " + prop.PropertyID + " " + prop.get_Value();
}
In this case to find Maximum DPI supported by your scanner you could use.
"Horizontal Optical Resolution" (property id: 3090)
"Vertical Optical Resolution" property id: 3091
.. However if you examine the properties enumeration you will see there is nothing to tell you the minimum or list of all available DPI settings.
.. Now I could not find anything either….
However I did find a way of discovering the minimum DPI…
You may be aware of WIA intent, the enumeration allows you to set scanning type e.g. colour, grey scale etc. (property id: 6146)
var currentIntent = item.Properties.get_Item("6146");
// set to colour
currentIntent.set_Value(WiaImageIntent.ColorIntent);
.. However you can also set WIA image bias in this way (to either maximum quality or minimum size)
This is not via image intent enumeration but is done by OR ing the appropriate values
// set minimum size as WIA bias
var intent = (int)item.Properties.get_Item("6146").get_Value();
item.Properties.get_Item("6146").set_Value(intent | 0x00010000);
http://msdn.microsoft.com/en-us/library/ms630190%28v=vs.85%29.aspx
And if you now look at the DPI (assuming previously DOI was not actually at minimum)
var dpiHorizontal = item.Properties.get_Item("6147").get_Value();
var dpiVertical = item.Properties.get_Item("6148").get_Value();
.. you should see that DPI is now set to it’s lowest (to give minimum size scan)
A big warning.
As soon as you set bias (be it minimum size or maximum quality) any previous DPI values you set are changed (as are various other properties for image dimensions etc – it makes wide ranging changes).
.. So, if you want to stay in control I suggest just finding minimum dpi once and storing it in configuration – Or if you do it each time, discard that item (after getting minimum DPI) and use a new item with no bias set.
.. So you now have max and min DPI values – how to get a list?
.. Again I know of no way .. but
You could have a list of “sensible DPI values”
e.g. 75, 100, 150, 200, 300, 600, 1200, 2400
As (depending on scanner resolution) these are “popular” values to support
.. Depending on your max / min DPI values you know what “popular” values may be worth trying.
.. and when setting DPI do it via try / catch
e.g.
try
{
item.Properties.get_Item("6147").set_Value(myDPI); // horizontal DPI
item.Properties.get_Item("6148").set_Value(myDPI); // vertical DPI
}
catch
{
// not supported so have some logic where try a different “popular” value
}
I see this type of issue with one scanner I use – just because a DPI is within the max / min limits does not mean it is supported.
Although many scanners WIA drivers support 100, 100 DPI, this one does not but does provide 75,75 DPI or 150,150 DPI
This approach is nasty and kludgy but works (and again you could just do this once, run through your list of popular “DPI” values, try and set them, and be left with a list of which DPI settings your scanner supports.
For the sake of simplicity sake these pseudocode examples assume vertical & horizontal DPI may both be set to same value .. this may not be the case with all scanners!
You can use the SubTypeMin and SubTypeMax properties of WIA_IPS_XRES and WIA_IPS_YRES to get the allowed resolution ranges. You can probably use something similar to determine which page sizes are supported.
WIA.Property horizontalResolutionProperty = FindProperty(_scannerDevice.Items[1].Properties, HORIZONTAL_RESOLUTION);
if (horizontalResolutionProperty != null)
{
// SubTypeMin and SubTypeMax are subproperties that tell what the min and max values are for the given property
if (horizontalResolutionProperty.SubTypeMin > minResolution) minResolution = horizontalResolutionProperty.SubTypeMin;
if (horizontalResolutionProperty.SubTypeMax < maxResolution) maxResolution = horizontalResolutionProperty.SubTypeMax;
}
WIA.Property verticalResolutionProperty = FindProperty(_scannerDevice.Items[1].Properties, VERTICAL_RESOLUTION);
if (verticalResolutionProperty != null)
{
// SubTypeMin and SubTypeMax are subproperties that tell what the min and max values are for the given property
if (verticalResolutionProperty.SubTypeMin > minResolution) minResolution = verticalResolutionProperty.SubTypeMin;
if (verticalResolutionProperty.SubTypeMax < maxResolution) maxResolution = verticalResolutionProperty.SubTypeMax;
}
The horizontal and vertical resolution properties have a Subtype property which, depending on it's value, let you acces the allowed value or values for the resolution:
var xResolutionProperty = item.Properties["Horizontal Resolution"];
switch (xResolutionProperty.SubType)
{
case WIASubType.ListSubType:
// Here you can access property SubTypeValues, which contains a list of allowed values for the resolution.
break;
case WIASubType.RangeSubTypes:
// Here you can access SubTypeMin and SubTypeMax properties, with the minimum and maximum allowed values.
break;
case WIASubType.UnspecifiedSubType:
// Here you can access SubTypeDefault property, which contains the default resolution value.
break;
}

Error in Pyramid mean shift filtering of image of certain dimensions?

I'm trying to run the mean shift segmentation using pyramids as explained in the Learning OpenCV book on some images. Both source and destination images are 8-bit, three-channel color images of the same width and height as mentioned.
However correct output is obtained only on a 1600x1200 or 1024x768 images. Other images of sizes 625x391 and 644x438 are causing a runtime error
"Sizes of input arguments do not match in function cvPyrUp()"
My code is this:
IplImage *filtered = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
cvPyrMeanShiftFiltering( img, filtered, 20, 40, 1);
The program uses the parameters as given in the sample. I've tried decreasing values thinking it to be an image dimensions problem, but no luck.
By resizing image dimensions to 644x392 and 640x320 the mean-shift is running properly. I've read that "pyramid segmentation requires images that are N-times divisible by 2, where N is the number of pyramid layers to be computed" but how is that applicable here?
Any suggestions please.
Well you have anything wring except that when you apply cvPyrMeanShiftFiltering
you should do it like this:
//A suggestion to avoid the runtime error
IplImage *filtered = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
cvCopy(img,filtered,NULL);
//Values only you should know
int level = kLevel;
int spatial_radius = kSpatial_Radius;
int color_radius = = kColor_Radius;
//Here comes the thing
filtered->width &= -(1<<level);
filtered->height &= -(1<<level);
//Now you are free to do your thing
cvPyrMeanSihftFiltering(filtered, filtered,spatial_radius,color_radius,level);
The thing is that this kind of pyramidal filter modifies som things acording the level you use. Try this and tell me later if worked.
Hope i can help.

Resources