Difference between Direct3D and DXGI - c++

I'm trying to query a Windows machine, using C++, for a list of available graphics cards.
This SO question has an answer (from moxize) which provides one way (d3d9.h):
get-the-graphics-card-model
And this one provides another (dxgi.h): dxgi enumadapters
When I tried each, I found the dxgi method above listed all the cards whilst the d3d9 one seemed only to provide one of them, depending on the selection of the "preferred graphics processor" in the NVIDIA control panel.
I'm struggling to understand the difference between what each of the above programmatic routes provides and is meant to be used for?

The DirectX Graphics Infrastructure (DXGI) was introduced with Vista. It basically factored all the enumeration, display and adapter management, and presentation stuff out of Direct3D. That way, all sorts of graphics APIs can coexist without a need to have separate mechanisms for these common tasks in each of them. It allows, e.g., all the Direct3D APIs (>= 10) to only be concerned with drawing 3D content into buffers and not care about where these buffers come from, or whether and how they are going to be displayed.
The old Direct3D 9 API still has its own interface for adapter enumeration. If I remember correctly, Direct3D 9 used to only enumerate adapters that actually had a display connected. Most likely because the API didn't really have support for headless rendering, so it wouldn't make sense to try use an adapter without an output. DXGI, on the other hand, operates on a more complete picture of the whole video and present network on your machine. Most importantly, it differentiates between adapters (graphics cards), and outputs (displays connected to an adapter). I assume you're running on a laptop or some other machine with an integrated as well as a dedicated GPU!? Switching the "preferred graphics processor" in the driver control panel will, most likely, change which of the two GPUs is (logically) connected to the display. And Direct3D 9 will then always only enumerate that oneā€¦

Related

directx game on laptops with two video adapters and the wrong one connected the output

I'm having a problem with a directx 11 game I'm developing on laptops with two video cards. The normal case I'm running into (and I have this on my own laptop) is a weak intel card and a powerful nvidia card. Obviously I want the nvidia one and I've already got it enumerating the adapters and figuring out the correct one to create the device interface for.
The problem is nvidia one doesn't have an output. When you call EnumOutputs on the IDXGIAdapter interface you don't find any. And this makes sense because the laptop only has one screen and its attached to the intel adapter (you can find it by calling EnumOutputs on the intel IDXGIAdapter interface).
But this seemingly makes it impossible to create a fullscreen swap chain for that device (IDXGIFactory::CreateSwapChain fails when given the nvidia device and fullscreen settings even when I'm certain the other mode parameters are valid).
It seems like other games are figuring out a way around this. Off of my steam list for example Half-Life 2 seems to be running in fullscreen mode. However stardew valley is running in borderless windowed mode which I could do but has its own issues.
I'm aware that its possible to change the laptop's settings so the nvidia card is the dominate one. But I need this to work on customer's laptops where I can't expect them to deal with all that.
One potential solution might be create a device for both adapters and then create a swap chain on the intel one as a device shared resource https://learn.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11device-opensharedresource I'm not even sure if that's possible though. The docs are vague.
Before I go down a difficult potentially dead end though I'm wondering if anyone knows the solution.

JOGL check extension availability before creating any GLCanvas

To check extension availability, I need to use GL.isExtensionAvailable. In order to get the GL object, I need to create some GLCanvas and get the GL instance in init() or display().
Is there a way to check the extension availability even before I create the window, at the beginning of main()?
I guess you are out of luck. The availability of some extension may change according to which video card is connected to the screen you want to visualize your GL content, so you cannot get reliably that information before creating the GL context. You may be able to create an offscreen context only to get that information, however result may differ from a context bound to a window
It's possible to call GLContext.getCurrent().getPlatformExtensionsString() very early but it will return a non null value only when the OpenGL context has been made current at least once and on the appropriate thread. Don't forget to call GLProfile.initSingleton() before calling GLContext.getCurrent().
However, pqnet's comment is correct. Numerous computers (especially modern laptops) have several graphics cards and mechanisms difficult to understand to switch to another one (for example Optimus) depending on the power consumption, the performance profile ("high performance" or not).
Moreover, different drivers might be supported (the crappy GDI renderer and the true OpenGL driver under Windows), several profiles are often supported (forward compatible and backward compatible profiles, ES profiles even on desktop machines), ... JOGL will do its best to pick the most capable one but it can use different ones for offscreen and onscreen. The first OpenGL context used by GLProfile and the one used by the first created drawable can be very different.
This problem isn't only a problem with JOGL. My suggestion helps to know which extensions are available with the default device. You can use GLProfile.glAvailabilityToString() and GLProfile.getDefault() too.
N.B: I assume that you use at least JOGL 2.3.1. The maintenance of JOGL 1 was stopped about 5 years ago.

Setup OpenGL for multiple monitors

I am beginning OpenGL programming on a Windows 7 computer and my application is made up of fullscreen windows where there is a separate window and thread for each monitor. What are the steps I have to take to have a continuous scene? I am still confused about many OpenGL concepts and how I should handle this. Is it basically the same as single monitor render except with view matrix and context extra work, or is it more complicated?
EDIT:
I found a website with information, but it is vague and without example code:
http://www.rchoetzlein.com/theory/2010/multi-monitor-rendering-in-opengl/
My first question would be why do you need two different OpenGL windows?
Have you considered the solution that the games industry has been using already? Many 3D applications and games that support multi-monitor setups don't actually manage their own separate windows, but let the GPU manage rendering over multiple screens. I used this in a project this year to have an oculus rift view and a spectator view on a TV screen. I didn't manage two OpenGL scenes, just two different "cameras".
http://www.amd.com/en-us/innovations/software-technologies/eyefinity
http://www.nvidia.com/object/3d-vision-surround-technology.html
Pros
Easier to code for. You just treat your code as being one scene, no weird scene management needed.
Graceful degradation. If your user only has one screen instead of two your app will still behave just fine sans a few UI details.
Better performance (Anecdotal). In my own project I found better performance over using two different 3D windows.
Cons
Lack of control. You're at the behest of driver providers. For example nVidia surround requires that GPUs be setup in SLI for whatever reason.
Limited support. Only relatively new graphics card support this multi monitor technology.
Works best wheen screens are same resolution. Dealing with different aspect ratios and even resolutions of the same aspect ratio can be difficult.
Inconvenient. The user will have to setup their computer to be in multi monitor mode when they may have their own preferred mode.

Is it possible to render one half of a scene by OpenGL and other half by DirectX

My straight answer would be NO. But I am curious how they created this video http://www.youtube.com/watch?v=HC3JGG6xHN8
They used video editing software. They recorded two nearly deterministic run-throughs of their engine and spliced them together.
As for the question posed by your title, not within the same window. It may be possible within the same application from two windows, but you'd be better off with two separate applications.
Yes, it is possible. I did this as an experiment for a graduate course; I implemented half of a deferred shading graphics engine in OpenGL and the other half in D3D10. You can share surfaces between OpenGL and D3D contexts using the appropriate vendor extensions.
Does it have any practical applications? Not many that I can think of. I just wanted to prove that it could be done :)
I digress, however. That video is just a side-by-side of two separately recorded videos of the Haven benchmark running in the two different APIs.
My straight answer would be NO.
My straight answer would be "probably yes, but you definitely don't want to do that."
But I am curious how they created this video http://www.youtube.com/watch?v=HC3JGG6xHN8
They prerendered the video, and simply combined it via video editor. Because camera has fixed path, that can be done easily.
Anyway, you could render both (DirectX/OpenGL) scenes onto offscreen buffers, and then combine them using either api to render final result. You would read data from render buffer in one api and transfer it into renderable buffer used in another api. The dumbest way to do it will be through system memory (which will be VERY slow), but it is possible that some vendors (nvidia, in particular) provide extensions for this scenario.
On windows platform you could also place two child windows/panels side-by-side on the main windows (so you'll get the same effect as in that youtube video), and create OpenGL context for one of them, and DirectX device for another. Unless there's some restriction I'm not aware of, that should work, because in order to render 3d graphics, you need window with a handle (HWND). However, both windows will be completely independent of each other and will not share resources, so you'll need 2x more memory for textures alone to run them both.

What is OpenGL as a computer file

Ok, I know that online there are millions of answers to what OpenGL is, but I'm trying to figure out what it is in terms of a file on my computer. I've researched and found that OpenGL acts as a multi-platform translator for different computer graphics cards. So, then, is it a dll?
I was wondering, if it's a dll, then couldn't I download any version of the dll (preferably the latest), and then use it, knowing what it has?
EDIT: Ok, so if it's a windows dll, and I make an OpenGL game that uses a late version, what if it's not supported on someone else's computer with an earlier version? Am I allowed to carry the dll with my game so that it's supported on other windows computers? Or is the dll set up to communicate with the graphics card strictly on specific computers?
OpenGL is constantly being updated (whatever it is). How can this be done if all it's doing is communicating with a graphics card on a bunch of different computers that have graphics cards that are never going to be updated since they're built in?
There are two "parts" to OpenGL - the specification that's updated by the Khronos Group once every few months, and the driver that's written by your graphics card manufacturer specifically for your graphics card model.
The OpenGL specification essentially details how everything about the OpenGL API should work - what the expected behavior should be, when something is considered unexpected behavior, when to throw which errors, etc. The specification lets the driver writers know exactly what they need to do and lets application writers know what to expect from a driver. This is what OpenGL really "is" - the glue that holds applications and drivers together. You can read all the specifications for each version here.
Then there's drivers that implement the OpenGL API and are considered compliant to the specification. The driver does exactly what you'd expect it to do - copy data to and from the graphics card's memory, write data to graphics card registers, keep track of state, process vertices, compile shaders, instruct hundreds of stream processors to simultaneously transform vertices and fill pixels, etc. Without OpenGL, each graphics card model would have a separate, slightly faster API that would only work for that one graphics card because of the way it was structured. With OpenGL, the drivers are all written against the same API and an application's code will run on all graphics cards.
Compliance to the OpenGL specification doesn't change with driver updates. Most driver updates will either fix minor bugs or do some internal optimizing.
I know at one point there was a small bug with ATI driver where you had to call glEnable(GL_TEXTURE_2D); before you could generate mipmaps the OpenGL 3 way (glGenerateMipMaps()) despite GL_TEXTURE_2D being deprecated as a possible value for glEnable(). I'm not sure if it's fixed now, but it's certainly the type of edge case that can easily be overlooked by driver writers.
As for optimizations, there's a lot to optimize. Maybe there's another way to optimize shaders when they're being compiled, maybe there's a more efficient way to distribute work between the stream processors, I don't know.
OpenGL is a cross-platform API for graphics programming. In terms of compiled code, it will be available as an OS-specific library - e.g. a DLL (opengl32.dll) in Windows, or an SO in Linux.
You can get the SDK and binary redistributables from OpenGL.org
Depending on which language you're using, there may be OpenGL wrappers available. These are classes or API libraries designed to specifically work with your language. For example, there are .NET OpenGL wrappers available for C# / VB.NET developers. A quick Google search on the subject should give you some results.
The OpenGL API occasionally has new versions released, but these updates are backwards-compatible in nature. Moreover, new features are generally added as extensions, and it's possible to detect which extensions are present and only use those which are locally available and supported... so you can build your software to take advantage of new features when they're available but still be able to run when they aren't.
The API has nothing to do with individual drivers -- drivers can be updated without changing the API, and so the fact that drivers are constantly updated does not matter for purposes of compatibility with your software. On that account, you can choose an API version to develop against, and as long as your target operating systems ships with a version of the OpenGL library compatible with that API, you don't need to worry about driver updates breaking your software's ability to be dynamically linked against the locally available libraries.