I am trying to render DirectX12 in SwapChainPanel by using SharpDx but creating a SwapChain fails for an unknown reason. Here is a simplified version of what I have:
// select adapter based on some simple scoring mechanism
SelectedAdapter = SelectAdapter();
// create device
using (var defaultDevice = new Device(SelectedAdapter, FeatureLevel.Level_12_0))
Device = defaultDevice.QueryInterface<SharpDX.Direct3D12.Device2>();
// describe swap chain
SwapChainDescription1 swapChainDescription = new SwapChainDescription1
{
AlphaMode = AlphaMode.Ignore,
BufferCount = 2,
Format = Format.R8G8B8A8_UNorm,
Height = (int)(MainSwapChainPanel.RenderSize.Height),
Width = (int)(MainSwapChainPanel.RenderSize.Width),
SampleDescription = new SampleDescription(1, 0),
Scaling = Scaling.Stretch,
Stereo = false,
SwapEffect = SwapEffect.FlipSequential,
Usage = Usage.RenderTargetOutput
};
// create swap chain
using (var factory2 = SelectedAdapter.GetParent<Factory2>())
{
/*--> throws exception:*/
SwapChain1 swapChain1 = new SwapChain1(factory2, Device, ref swapChainDescription);
SwapChain = swapChain1.QueryInterface<SwapChain2>();
}
// tie created swap chain with swap chain panel
using (ISwapChainPanelNative nativeObject = ComObject.As<ISwapChainPanelNative>(MainSwapChainPanel))
nativeObject.SwapChain = SwapChain;
Selection of adapter works as expected (I have 2 adapters + software adapter). I can create a device and I can see that the app in task manager is using that selected adapter.
Creation of the swap chain is based mostly on this documentation here: https://learn.microsoft.com/en-us/windows/uwp/gaming/directx-and-xaml-interop#swapchainpanel-and-gaming
I get factory2 (with all the adapters and other things enumerated). Constructor of SwapChain1 internally is using factory2 to create a swap chain: https://github.com/sharpdx/SharpDX/blob/master/Source/SharpDX.DXGI/SwapChain1.cs#L64
I compared this method with several others examples and tutorials and this is the way it should be done, however, regardless of the Format I choose or adapter, I keep getting this exception:
{SharpDX.SharpDXException: HRESULT: [0x887A0001], Module:
[SharpDX.DXGI], ApiCode: [DXGI_ERROR_INVALID_CALL/InvalidCall],
Message: The application made a call that is invalid. Either the
parameters of the call or the state of some object was incorrect.
Enable the D3D debug layer in order to see details via debug messages.
at SharpDX.Result.CheckError() at
SharpDX.DXGI.Factory2.CreateSwapChainForComposition(IUnknown
deviceRef, SwapChainDescription1& descRef, Output restrictToOutputRef,
SwapChain1 swapChainOut) at SharpDX.DXGI.SwapChain1..ctor(Factory2
factory, ComObject device, SwapChainDescription1& description, Output
restrictToOutput) at UI.MainPage.CreateSwapChain()}
DebugLayer doesn't show any additional info.
The app itself is a regular Windows Universal Blank App (min target version Creators Update 15063). I know I can run Directx12 on my current hardware (C++ hello world works just fine).
Any ideas what is wrong?
This is how I got it working:
try
{
using (var factory4 = new Factory4())
{
SwapChain1 swapChain1 = new SwapChain1(factory4, CommandQueue, ref swapChainDescription);
SwapChain = swapChain1.QueryInterface<SwapChain2>();
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return;
}
using (ISwapChainPanelNative nativeObject = ComObject.As<ISwapChainPanelNative>(MainSwapChainPanel))
nativeObject.SwapChain = SwapChain;
So basically I need Factory4 interface to create temporary SwapChain1 from which I can query SwapChain2, then this SwapChain2 can be attached to SwapChainPanel.
Also, a very important thing to notice here is that even though SwapChain1 constructor signature (and documentation) https://github.com/sharpdx/SharpDX/blob/master/Source/SharpDX.DXGI/SwapChain1.cs#L51 says that 2nd argument should be device - it shouldn't. What you need to pass is a CommandQueue object. I have no idea why.
Also, constructor of SwapChain1 says it needs Factory2, but no, you have to pass Factory4!
Related
Background: I'm trying to write a program to insert an image into a cell of a spreadsheet. LibreOffice recently changed how this is done, and all the samples I could find use the old method which no longer works.
Technically I know that you can't "insert" an image into a cell and that such an image is an overlay on a DrawPage that sits on top of the spreadsheet to "decorate" it.
One of the first steps in doing this (the new way) is to create an XGraphic object which contains the image. The process is to create an XGraphicProvider and call it with MediaProperties that specify the image file URL to be loaded. I have a program that is supposed to do this but the resulting XGraphic is null. The LO SDK gives pretty much no information when you do something wrong; it just doesn't work.
Here is the code I have, with all the headers removed:
// addpic
// add picture to spreadsheet - debug version
class OpenOfficeApp {
[STAThread]
static void Main(string[] args) {
bool lreadonly;
string pqfile;
string pqURL;
string pqpic;
pqfile = "file:///D:/Documents/NSexeye/ODS%20File%20Access/"+
"addpix/addpic.ods";
pqpic = "addpic2";
pqURL = pqpic+".jpg";
lreadonly = false;
Console.WriteLine("Using: "+pqfile);
// get the desktop
XComponentContext XCC = uno.util.Bootstrap.bootstrap();
XMultiComponentFactory XMCF =
(XMultiComponentFactory)XCC.getServiceManager();
XMultiServiceFactory XMSF = (XMultiServiceFactory)XCC.getServiceManager();
XComponentLoader XCL =
(XComponentLoader)XMSF.createInstance("com.sun.star.frame.Desktop");
// open the spreadsheet
PropertyValue[] pPV = new PropertyValue[2];
pPV[0] = new PropertyValue();
pPV[0].Name = "Hidden";
pPV[0].Value = new uno.Any(true);
pPV[1] = new PropertyValue();
pPV[1].Name = "ReadOnly";
if (lreadonly) pPV[1].Value = new uno.Any(true);
else pPV[1].Value = new uno.Any(false);
XComponent XCo = XCL.loadComponentFromURL(pqfile,"_blank",0,pPV);
// create graphic object containing image
object oGP = XMCF.createInstanceWithContext(
"com.sun.star.graphic.GraphicProvider",XCC);
if (oGP == null) {
Console.WriteLine("oGP is null. Aborting.");
return;
}
XGraphicProvider XGP = (XGraphicProvider)oGP;
if (XGP == null) {
Console.WriteLine("XGP is null. Aborting.");
return;
}
pPV = new PropertyValue[1];
pPV[0] = new PropertyValue();
pPV[0].Name = "URL";
pPV[0].Value = new uno.Any(pqURL);
Console.WriteLine("Creating XGraphic containing "+pqURL);
XGraphic XG = XGP.queryGraphic(pPV);
// *** XG is null here
if (XG == null) {
Console.WriteLine("XG is null. Aborting.");
return;
}
// ... lots of stuff to be added here
// save and close the spreadsheet
XModifiable XM = (XModifiable)XCo;
XM.setModified(true);
XStorable XSt = (XStorable)XCo;
XSt.store();
XCloseable XCl = (XCloseable)XCo;
XCl.close(true);
// terminate LibreOffice
// *** I want this to not terminate it if something else is open
XDesktop XD = (XDesktop)XCL;
if (XD != null) XD.terminate();
}
}
I get a null for the XGraphic, in the place indicated in the comments. I don't know if the call to create it is failing, or if one of the earlier steps of the process are incorrect.
My goal here, in addition to getting my program working, is to create a sample program showing how to add an image to a Calc spreadsheet cell, and to manipulate such images. There are a fair number of people asking questions about this and none of the examples I've found will work. I think a good working sample will be of value.
I've spent a lot of time searching for information and code samples for this, with nothing that helps. I've tried to find ways to verify the validity of the XGraphicProvider interface with no luck. I've run out of things to try.
I'm hoping someone who knows about the LibreOffice SDK can take a look and maybe see what I'm doing wrong.
Update: I figured out what I was doing wrong: I was passing a bare filename in the "URL" property to XGraphicProvider. It has to be the same format (starting with "file:///") as the spreadsheet's file name specification.
Now I'm stuck with another property problem. The XGraphic has to be specified as a parameter to the GraphicObjectShape's Graphic property, but the setPropertyValue() function requires that it be a uno.Any type. I can't figure out how to specify an interface name like XGraphic as a uno.Any.
Here is the piece of code that won't compile, complaining that it can't convert an XGraphic to a uno.Any, in the first setPropertyValue call:
// set image XGraphic
XPropertySet XPS = (XPropertySet)XS;
XPS.setPropertyValue("Graphic",XG);
XPS.setPropertyValue("Name",new uno.Any(pqpic));
XG is an XGraphic type. Using "new uno.Any(XG)" doesn't work either, giving a similar compiler error.
After trying unsuccessfully for a few hours to get the latest LO SDK up and running, let me offer some untested ideas.
First of all, here is some working Basic code, no doubt similar to what you're translating from. The important line is oShape.Graphic = oProvider.queryGraphic(Props()).
oDoc = ThisComponent
oSheet = oDoc.CurrentController.ActiveSheet
pqURL = "file:///C:/Users/JimK/Desktop/addpic.jpg"
oProvider = createUnoService("com.sun.star.graphic.GraphicProvider")
oShape = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
Dim Props(0) as new com.sun.star.beans.PropertyValue
Props(0).Name= "URL"
Props(0).Value = pqURL
oShape.Graphic = oProvider.queryGraphic(Props())
oCell = oSheet.getCellByPosition(5,5)
oShape.Name = oCell.AbsoluteName + "##" + Props(0).Value
oShape.Anchor = oCell
oSheet.DrawPage.add(oShape)
'Resize
w = oShape.Graphic.Size.Width
h = oShape.Graphic.Size.Height
wcl = oCell.Size.Width
hcl = oCell.Size.Height
If w<>0 and h<>0 then
oCell.String=""
Dim Size as new com.sun.star.awt.Size
Size.Width = wcl
Size.Height = h*wcl/w
If Size.Height > hcl then
Size.Width = hcl*w/h
Size.Height = hcl
Endif
oShape.setSize(Size)
oShape.setPosition(oCell.Position)
erase oShape
Else
oShape.dispose()
Endif
Now, how to translate this to C#? It looks like you may need to explicitly specify the type. In the SDK example, there are calls like this.
xFieldProp.setPropertyValue(
"Orientation",
new uno.Any(
typeof (unoidl.com.sun.star.sheet.DataPilotFieldOrientation),
unoidl.com.sun.star.sheet.DataPilotFieldOrientation.DATA ) );
So in your case, something like this:
XPS.setPropertyValue(
"Graphic"
new uno.Any(
typeof(unoidl.com.sun.star.graphic.XGraphic),
XG));
Alternatively, follow the suggestion here: set GraphicURL, which should load the image and set Graphic for you.
I am trying to write a program that will set webcam settings according to a stored preset. I'm using C# and DirectShow.Net. So far I was able to access all the settings sans the ones mentioned.
To read settings I use the following code:
DsDevice[] capDevices;
// Get the collection of video devices
capDevices =
DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
// Select first camera
var dev = capDevices[0];
int hr;
IBaseFilter capFilter = null;
ICaptureGraphBuilder2 capGraph = null;
// Get the graphbuilder object
IFilterGraph2 m_FilterGraph = (IFilterGraph2)new FilterGraph();
try
{
// Get the ICaptureGraphBuilder2
capGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
/// Start building the graph
hr = capGraph.SetFiltergraph(m_FilterGraph);
DsError.ThrowExceptionForHR(hr);
// Add the video device
hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, "Video input", out capFilter);
DsError.ThrowExceptionForHR(hr);
int value;
// Reset settings
cameraSettings.Reset();
// Get IAMVideoProcAmp Values
IAMVideoProcAmp pVideoAmp = (IAMVideoProcAmp)capFilter;
VideoProcAmpFlags vpaFlags;
pVideoAmp.Get(VideoProcAmpProperty.Brightness, out value, out vpaFlags);
.....
// Get IAMCameraControl Values
IAMCameraControl pCameraControl = (IAMCameraControl)capFilter;
CameraControlFlags ccFlags;
pCameraControl.Get(CameraControlProperty.Exposure, out value, out ccFlags);
.....
However, neither of the interfaces allows getting those two values. I will attach a screenshot that shows those values accessible in the typical windows interface for webcam settings:
How can I access those values via DirectShow.Net?
These property pages are communicating with the filter objects using IAMVideoProcAmp and IAMCameraControl interfaces respectively. That is, IAMVideoProcAmp::Set and IAMCameraControl::Set are the methods called by property page implementation and they can similarly be used by applications programmatically.
Property enumerations do not have defined values for powerline frequency and low light compensation because SDK and documentation was no longer updated to indicate values from extended enumerations, however new properties do exist. Specifically, they exist in stock property pages implementation.
The named and documented property values are available from lower layer SDK definitions:
KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY = 13
KSPROPERTY_CAMERACONTROL_AUTO_EXPOSURE_PRIORITY = 19
In Epicor 9 it was fairly easy to open Visual Studio and create a project and use the Epicor libraries to access its Business Objects (BOs). So, for instance the Part could be accessed by including the library Epicor.Mfg.Part and newing up a Part object. Then it was easy to get information for a part by calling Part.GetByID("partnum");. This would return a PartDataSet.
It is different but not so difficult to do the same thing in Epicor 10. However, I have noticed that the PartDataSet does not contain any UD fields, even UD fields that have been properly set up in Epicor10.
How can the UD fields be accessed when tapping into Epicor 10 through its business objects?
EDIT:
using Erp.BO;
using Erp.Proxy.BO;
// ...
var binding = Epicor.ServiceModel.StandardBindings.NetTcp.UsernameWindowsChannel();
var cc = new ClientCredentials();
var cred = cc.UserName;
cred.UserName = "****";
cred.Password = "****";
DnsEndpointIdentity ep = new DnsEndpointIdentity("****");
var quoteBo = new QuoteImpl(binding, new Uri("net.tcp://****/Erp/BO/Quote.svc"), cc, ep);
var qds = new QuoteDataSet();
var hed = qds.QuoteHed.NewQuoteHedRow(); // type: QuoteDataSet.QuoteHedRow
// I am not getting UserDefinedColumns as a member of hed.
// This gives me a compiler error.
qds.QuoteHed[0].UserDefinedColumns["Custom_c"] = "value";
It is still fairly easy, the DS returned by the call to the BO will be defined in the contract DLL found on both the client and the server, as this file needs to be distributed to the client machines the UD fields are not added to it. It would cause too many client updates.
This means the Visual Studio cannot look at the contract assembly to determine the field names. Instead, you access the field using the columnName indexer i.e:
class Program
{
static void Main(string[] args)
{
// Hard-coded LogOn method
// Reference: Ice.Core.Session.dll
Ice.Core.Session session = new Ice.Core.Session("manager", "manager", "net.tcp://AppServer/MyCustomerAppserver-99999-10.0.700.2");
// References: Epicor.ServiceModel.dll, Erp.Contracts.BO.ABCCode.dll
var abcCodeBO = Ice.Lib.Framework.WCFServiceSupport.CreateImpl<Erp.Proxy.BO.ABCCodeImpl>(session, Erp.Proxy.BO.ABCCodeImpl.UriPath);
// Call the BO methods
var ds = abcCodeBO.GetByID("A");
var row = ds.ABCCode[0];
System.Console.WriteLine("CountFreq is {0}", row.CountFreq);
System.Console.WriteLine("CustomField_c is {0}", row["CustomField_c"]);
System.Console.ReadKey();
}
}
UserDefinedColumns is defined in Epicor.ServiceModel but is inaccessible as it is an internal property of Ice.IceRow which Erp.Tablesets.QuoteHedRow inherits from.
When you've found the specific record your looking for and have an object containing all of the columns for the record you should see an additional object named UserDefinedColumns. It works like a dictonary that is of type <string, object>. So for instance to set a value out you would do something like this:
myPartDs.Part[0].UserDefinedColumns["MyUdColumn_c"] = "some value";
If you need to pull a value out then you will have to parse it to whatever type it needs to be because they are stored as objects.
Using NotificationHubClient I can get all registered devices using GetAllRegistrationsAsync(). But if I do not use the registration model but the installation model instead, how can I get all installations? There are methods to retrieve a specific installation but none to get everything.
You're correct, as of July 2016 there's no way to get all installations for a hub. In the future, the product team is planning to add this feature to the installations model, but it will work in a different way. Instead of making it a runtime operation, you'll provide your storage connection string and you'll get a blob with everything associated with the hub.
Sorry for visiting an old thread... but in theory you could use the GetAllRegistrationsAsyc to get all the installations. I guess this will return everything without an installation id as well, but you could just ignore those if you choose.
Could look something like this
var allRegistrations = await _hub.GetAllRegistrationsAsync(0);
var continuationToken = allRegistrations.ContinuationToken;
var registrationDescriptionsList = new List<RegistrationDescription>(allRegistrations);
while (!string.IsNullOrWhiteSpace(continuationToken))
{
var otherRegistrations = await _hub.GetAllRegistrationsAsync(continuationToken, 0);
registrationDescriptionsList.AddRange(otherRegistrations);
continuationToken = otherRegistrations.ContinuationToken;
}
// Put into DeviceInstallation object
var deviceInstallationList = new List<DeviceInstallation>();
foreach (var registration in registrationDescriptionsList)
{
var deviceInstallation = new DeviceInstallation();
var tags = registration.Tags;
foreach(var tag in tags)
{
if (tag.Contains("InstallationId:"))
{
deviceInstallation.InstallationId = new Guid(tag.Substring(tag.IndexOf(":")+1));
}
}
deviceInstallation.PushHandle = registration.PnsHandle;
deviceInstallation.Tags = new List<string>(registration.Tags);
deviceInstallationList.Add(deviceInstallation);
}
I am not suggesting this to be the cleanest chunk of code written, but it does the trick for us. We only use this for debugging type purposes anyways
So, I'm writing an app to 'flesh out' new clients in Rally. It will have tools to create templates which will add first:
add a 'Feature'
add 'UserStories' under that 'Feature'
add 'Tasks' under those 'UserStories' individually
I have figured out step 1. But how to associate anything I can't figure out from the horrible and cryptic documentation. Here's what I have so far:
var FeatureToAdd = _featureRepository.GetFeatures().FirstOrDefault(x => x.Id == 2);
// Initialize the REST API. You can specify a web service version if needed in the constructor.
RallyRestApi restApi = GetRallyRestApi();
//Create an item
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate["Name"] = FeatureToAdd.Name;
toCreate["Description"] = FeatureToAdd.Description;
// important to which this belongs, but I no ID I ever use works
//toCreate["Workspace"] = "/workspace/" + WebConfigurationManager.AppSettings["RallyAPIWorkspaceID"];
//toCreate["Project"] = "/project/XXXXX";
//toCreate["Iteration"] = "/iteration/XXXXXX";
// create feature - feature is under PortfolioItem
CreateResult createFeatureResult = restApi.Create("PortfolioItem/Feature", toCreate);
// scrape ID off the end of the reference
var pureId = createFeatureResult.Reference.Substring(createFeatureResult.Reference.LastIndexOf('/') + 1);
// add UserStories
foreach (UserStory u in FeatureToAdd.UserStories)
{
toCreate = new DynamicJsonObject();
toCreate["Name"] =u.Name;
toCreate["Description"] = u.Description;
toCreate["WorkProduct"] = "PortfolioItem/Feature/" + pureId;
//toCreate["WorkProduct"] = createFeatureResult.Reference;<- tried this too
// hierarchicalrequirement = UserStory
CreateResult createUserStoryResult = restApi.Create("hierarchicalrequirement", toCreate);
}
Running this creates both, but no association happens. I get a warning:
Ignored JSON element hierarchicalrequirement.WorkProduct during processing of this request.
Why did it arbitrarily ignore this?...
It ignored WorkProduct because WorkProduct is not a valid field on HierarchicalRequirement. The field you want to specify to set the feature parent of a story is called PortfolioItem.
toCreate["PortfolioItem"] = Ref.GetRelativeRef(createFeatureResult.Reference);
Also, object relationships are specified as in WSAPI as refs (/type/id) so you can just directly pass in the reference from the createFeatureResult.
Sorry you're finding the api to be frustrating. It definitely has some weird dark corners but once you use it a bit and get a feel for how the various domain objects are related I think you'll find it to be quite powerful and consistent.