DirectX 11 Win7 versus Win8 difference in brightness/shader ambient lighting - wpf

The problem shows on all Win8 systems, all brands, all types of desktop, laptop, all-in-one, and tablets (tested on nearly every system at BestBuy which there's a ton of them so I can't be the first person to see this.)
What is happening is shown in below image (note captions below each surface), where the rendering on Win8 is brighter than Win7 for native code and WinForm which is based off a windowed ID3D11Device/Context; and to make things worse; the rendering is darker via WPF and WPFs shared surface/texture features though using similar device/context. The actual rendering loop and shaders are identical. Win7/Vista render the same/ideal brightness via native type render target or WPF shared surface.
The DirectX 11 code was developed on Win7. It's very basic DX stuff and the shader is as simple a shader as possible; very similar to the most basic DirectX SDK examples.
Why is DX11 Win8 brightness not consistent with Win7? Gradients seem different too.
Why would Win8 WPF shared surface/texture create even more difference?
What is the best strategy to solve such rendering brightness differences?
I did end up answering, but welcome improvements or expand with related answers to brightness/lighting problems between win7 and win8 as searching the net for such topic shows little results.

After much work between me and MS, (MS wanted a repro without using DXUT even though I told them PNTriangles11 caused the issue and it was a wild goose chase.) I found it was related to EnumOutputs failing on Win8 (MS still to provide an official reason, I will update) and DXUT portions that call EnumOutputs fail resulting in the problematic section of code DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings)
where...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
should be changed to...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
which resolves the issue and color is consistent between Win7 and Win8. MS pointed this out. Though I'd like to know why EnumOutputs is failing on Win8 and MS is likely the only one possible to answer this. EnumOutputs failed on every Win8 system at BestBuy, all types of systems.
As for another DXUT modification needed for Win8 compatibility, within DXUTChangeDevice, adding a test for nonzero hAdapterMonitor is likely wanted...
bool bNeedToResize = false;
if(hAdapterMonitor && DXUTGetIsWindowedFromDS( pNewDeviceSettings ) && !bKeepCurrentWindowSize )
{
UINT nClientWidth;
UINT nClientHeight;
if( ::IsIconic( DXUTGetHWNDDeviceWindowed() ) )
For completeness as relates to topic title, gamma correction information can be found at directx gamma correction and new windows 8 brightness control features for integrated displays win8 brightness control

I'm currently testing my C++,DX10 program (based on DXUT June 2010) on Windows 8,
And I'm having the same problems.
Here are additional changes/advice that I advice to do on DXUT:
1) do NOT use the arguments /width, /height, /windowed, /fullscreen in the strExtraCommandLineParams of DXUTInit
2) in DXUTGetMonitorInfo, s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo ); returns FAIL on my system.
So I have replaced this line by something like:
BOOL success = s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo );
//try to return the less wrong result
if ( !success )
{
RECT rcWork;
if ( lpMonitorInfo &&
( lpMonitorInfo->cbSize >= sizeof( MONITORINFO ) ) &&
SystemParametersInfoA( SPI_GETWORKAREA, 0, &rcWork, 0 )
)
{
lpMonitorInfo->rcMonitor.left = 0;
lpMonitorInfo->rcMonitor.top = 0;
lpMonitorInfo->rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
lpMonitorInfo->rcWork = rcWork;
lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
return TRUE;
}
return FALSE;
}
else
{
return TRUE;
}
3) Concerning the brightness (gamma correction),
if have added:
if ( BackBufferFormat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB )
{
return false;
}
in my callback IsD3D10DeviceAcceptable, so I ban every gamma correction device.
And now everything seems to work
(BTW, I'm not sure to understand your "hAdapterMonitor &&" modification, because it doesn't use directly this pointer, but maybe we don't have the same DXUT version )

Related

ETW event tracing in WPF 4+

I am trying to use a Microsoft demo project which shows how to do ETW event tracing in WPF as a basis for some specific profiling I want to do in an app I'm developing.
Compiled as is, the demo works fine. However, change the target framework from .Net 3.5 to .Net 4, and it breaks. Clearly there is some significant change between the framework versions.
The question is what changed, and (more importantly) is it possible to fix the demo?
My investigation so far
Adding a Debug.WriteLine to FpsEventConsumer.EtwEventCallback I see that in framework 4 either no events arrive or two events arrive, both with Header.Guid of 68fdd900-4a3e-11d1-84f4-0000f80464e3; one with Header.Class.Type of UCE_GLASS_START and the other with UCE_GLYPHRUN_START. Note that I also observe these events, among many others, when testing under framework 3.5.
By digging around in referencesource.microsoft.com I discovered that MS.Utility.EventTrace's static field EventProvider of type MS.Utility.TraceProvider controls what gets sent to ETW. Using reflection to access the event provider (since it's non-public) I observe that in 3.5 it starts with everything enabled (_enabled is true, _flags is 2147483647, _level is 5); and in 4 it starts with everything disabled (_enabled is false, _keywords is 0, and _level is 0). But changing those values with reflection doesn't seem to help the situation much. At best, on a very rare occasion I get a few events emitted before the UCE_ ones mentioned above.
By placing a WriteLine in TraceConsumer.ProcessTrace as follows, I observe that the p/invoked call continues to block, so the problem isn't that the trace is being interrupted.
ErrorCode errorCode = UnsafeEventTrace.ProcessTrace(handleArray, handleArray.Length,
(FILETIME)startTime, (FILETIME)endTime);
+ System.Diagnostics.Debug.WriteLine("ProcessTrace: " + errorCode);
if (errorCode != ERROR.SUCCESS)
{
errorCode.OutputErrorMessage("TraceConsumer.ProcessTrace");
}
It turns out that the answer was there all along in one of the referencesource files I looked at:
/// ...
/// TreatAsSafe: it generates the GUID that is passed into the TraceProvider
/// WPF versions prior to 4.0 used provider guid: {a42c77db-874f-422e-9b44-6d89fe2bd3e5}
///</SecurityNote>
[SecurityCritical, SecurityTreatAsSafe]
static EventTrace()
{
Guid providerGuid = new Guid("E13B77A8-14B6-11DE-8069-001B212B5009");
...
The following simple patch to Sample.RunTrace causes events to start flowing (although they no longer include the particular event which the demo uses for the FPS).
- m_traceSession = TraceController.WpfController;
+ m_traceSession = typeof(System.Windows.Rect).Assembly.GetName().Version.Major == 3
+ ? TraceController.WpfController
+ : TraceController.GetController(new Guid("E13B77A8-14B6-11DE-8069-001B212B5009"), "WPF");

OpenCV Capture from external camera

I'm currently writing an real time application using OpenCV and in the following case:
I'm trying to capture an image from a HDV camera plugged in firewire 800.
I have tried to loop on index used on cvCaptureFromCam,
but no camera can't be found (except the webcam).
there is my code sample, it loop on index (escaping 0 cause it's the webcam's index) :
CvCapture* camera;
int index;
for (index = 1; index < 100; ++index) {
camera = cvCaptureFromCAM(index);
if (camera)
break;
}
if (!camera)
abort();
On any time it stops on the abort.
I'm compiling on OSX 10.7 and I have tested :
OpenCV 1.2 private framework
OpenCV 2.0 private framework (found here : OpenCV2.0.dmg)
OpenCV compiled by myself (ver. 2)
I know that the problem is knowned and there is a lot of discussion about this,
but I'm not able ti find any solution.
Does anyone have been in the same case ?
Regards.
To explicitly select firewire, perhaps you can try to add 300 to your index? At least in OpenCV 2.4, each type of camera is given a specific domain. For example, Video4Linux are given domain 200, so 200 is the first V4L camera, 201 is the second, etc. For Firewire, the domain is 300. If you specify an index less than 100, OpenCV just iterates through each of its domains in order, which may not be the order you expect. For example, it might find your webcam first, and never find the firewire camera. If this is not the issue, please accept my appologies.
index should start at 0 instead of 1.
If that doesn't work, maybe your camera is not supported by OpenCV. I suggest you check if it is in the compatibility list.

WPF WebBrowser - How to Zoom Content?

Trying to test basic browser concepts in a WPF (C#/XAML, .NET 4.0) WebBrowser application. So far, the only problem is programatically zooming. Has anyone had any experience with this?
MSDN lists nothing: http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.aspx
Additionally, I have tried various things such as RenderTransform options to no avail. Either this is not possible or not documented. I'm hoping for the latter. Note that a WinForm solution isn't acceptable.
Thanks in advance for any help,
Beems
Maybe you can execute a javascript like this.
document.body.style.zoom = 1.5;
In WPF we can manipulate the document. I Created a Extension Method for you, so you can set the Zoom:
// www.tonysistemas.com.br
public static partial class MyExtensions
{
public static void SetZoom(this System.Windows.Controls.WebBrowser WebBrowser1, double Zoom)
{
// For this code to work: add the Microsoft.mshtml .NET reference
mshtml.IHTMLDocument2 doc = WebBrowser1.Document as mshtml.IHTMLDocument2;
doc.parentWindow.execScript("document.body.style.zoom=" + Zoom.ToString().Replace(",", ".") + ";");
}
}
Usage:
WebBrowser1.SetZoom(0.5);
I used bits and pieces from this answer https://stackoverflow.com/a/7326179/17822 to assist with the zoom issue. The key here is the ExecWB method. The zoom on the Windows Desktop is not 1-1 to the zoom on the WebBrowser Control. You will have to play with it. The pseudo-code for the equation looks like this:
zoomLevel = (winDesktopZoom - 100) + _winDesktopZoom + 10
Note that you will need a reference to SHDocVw.dll which can be found in the C:\Windows\SysWOW64 for x64 machines and in C:\Windows\System32 for x86 machines.
This is not pretty, but it is the only thing that I have found, short of upgrading to http://awesomium.com that actually matches IE default zoom settings (which default to the Windows Desktop zoom) to WebBrowser Control. Also note that the Windows Desktop Zoom only exists for Vista, Win 7 and probably 2k8 as well in the Control Panel --> Display, but I didn't check Vista or 2k8. It is not there for XP (any service pack).
To get the Windows Desktop Zoom (this does work on XP for some reason) I did:
var presentSource = PresentationSource.FromVisual(this);
if (presentSource != null && presentSource.CompositionTarget != null
&& presentSource.CompositionTarget.TransformToDevice != null)
{
_zoomPercentage = Convert.ToInt32(100 * presentSource.CompositionTarget.TransformToDevice.M11);
}
This logic is placed in the OnSourceInitialized override for that XAML Window.
You can see this:
http://chriscavanagh.wordpress.com/2010/10/04/a-real-net-4-0-webbrowser/

Random GUI errors using C# Mono on Mac OS X

I'm developing an application in C# (Windows Forms), which uses Mono to run on Mac OS X.
It contains some dynamic controls, for example a custom groupbox which contains some labels and textboxes, a button, etc.These boxes can both be added and removed dynamically.
My CustomGrpBx inherits from GroupBox and this is the contructor I use:
public CustomGrpBx(Point CreateHere,Info Inf)
{
this.Name = Inf.Name;
this.Location = CreateHere;
CreateHere.Y = 10;
CreateHere.X = 10;
CreateHere.Y += 7;
Button btnPress = new Button();
btnPress.Location = CreateHere;
btnPress.Size = new Size(40, 24);
btnPress.Text = Name;
btnPress.Enabled = false;
this.Controls.Add(btnPress);
CreateHere.X += 45;
CreateHere.Y += 2;
TextBox txtName = new TextBox();
txtName.Location = CreateHere;
txtName.Size = new Size(75, 20);
txtName.Text = Name;
txtName.ReadOnly = true;
this.Controls.Add(txtName);
CreateHere.X += 80;
//More code here, but the same pattern as above
this.Size = new Size(CreateHere.X + 30, CreateHere.Y + 35);
}
The problem arises both when they are created, and removed, or even when a messagebox is shown.
What happens is that sometimes on rendering white boxes appears, or some labels are not drawn correctly. And sometimes when a messagebox appears, it first opens up like 5 dummies which are just blank, and which you can't close.
Am I doing something wrong, should I sleep the GUI thread a bit after each creation, or should I invalidate stuff on my own? Or should I try GTK#?
Many thanks on input on this.
It is hard to advise something without seeing actual code, but first of all, check your assembly with MoMa for incompatibility issues (for example, pinvoke's), if you primarily developed your project targeting .NET platform. Then, mono team claims that windows form support in mono is complete:
Support for Windows Forms 2.0 is complete. At this point, we are largely just fixing bugs and polishing our code.
So, you can try to run your project under .NET and see if the bug persists.
As for Gtk#. I think it is better to use gtk# if a primary OS for your project is OSX. At the very least you will be able to use some OSX-specific stuff, for example, integrate in it's toolbar. Look here for an open-source example of Gtk# project which uses some native OSX features and integrates well in it's environment. There also is a support for gtk# in MonoDevelop's designer.
P.S.
Some interesting Gtk# projects to play with:
Beagle,
Tomboy

Version detection with Silverlight

How can I efficiently and effectively detect the version and, for that matter, any available information about the instance of Silverlight currently running on the browser?
The Silverlight control only has an IsVersionSupported function, which returns true / false when you give it a version number, e.g.:
if(slPlugin.isVersionSupported("2.0")) {
alert("I haz some flavour of Silverlight 2");
You can be as specific as you want when checking the build, since the version string can include all of the following:
major - the major number
minor - the minor number
build - the build number
revision - the revision number
So we can check for a specific build number as follows:
if(slPlugin.isVersionSupported("2.0.30523")) {
alert("I haz Silverlight 2.0.30523, but could be any revision.");
Silverlight 1.0 Beta included a control.settings.version property, which was replaced with the isVersionSupported() method. The idea is that you shouldn't be programming against specific versions of Silverlight. Rather, you should be checking if the client has at least verion 1.0, or 2.0, etc.
That being said, you can get the Silverlight version number in Firefox by checking the Silverlight plugin description:
alert(navigator.plugins["Silverlight Plug-In"].description);
Shows '2.0.30523.8' on my computer.
Note that it is possible to brute force it by iterating through all released version numbers. Presumably that's what BrowserHawk does - they'll report which version of Silverlight the client has installed.
I got this from http://forums.asp.net/p/1135746/1997617.aspx#1997617 which is the same link Stu gave you. I just included the code snippet.
Silverlight.isInstalled = function(d)
{
var c = false, a = null;
try
{
var b = null;
if(Silverlight.ua.Browser == "MSIE")
b = new ActiveXObject("AgControl.AgControl");
else
if(navigator.plugins["Silverlight Plug-In"])
{
a = document.createElement("div");
document.body.appendChild(a);
a.innerHTML = '<embed type="application/x-silverlight" />';
b = a.childNodes[0]
}
if(b.IsVersionSupported(d))
c = true;
b = null;
Silverlight.available = true
}
catch(e)
{
c=false
}
if(a)
document.body.removeChild(a);
return c
};
found this site that detects the full version of silverlight- silverlight version (aka silverlightversion.com)
As mentioned in the above comments there is currently no efficient direct way to get the installed Silverlight version number (that works cross browser platform).
I wrote a post on how to workaround this problem and detect the Silverlight major version number (including version 3) programmatically and more efficiently using JavaScript.
You can find the code and the post at:
http://www.apijunkie.com/APIJunkie/blog/post/2009/04/How-to-programmatically-detect-Silverlight-version.aspx
Good luck!
Environment.Version will do what you want! Supported since Silverlight 2.0
Look in silverlight.js:
http://forums.asp.net/p/1135746/1997617.aspx#1997617

Resources