C++ and directx 11 Error no symbols loaded for dxgi.dll - c++

I started to lean c++ and directx11 a few days back.
So I am no expert at it. .Please be kind enough to explain me why it had occurred ...
I created the window and stuff correctly.Even the Swapchain initializtion proceeded as expected.But I am stuck at render Targetview Initializtion...
When ever i debug it gives me the following error
dxgiDevice 0x008959ac <Information not available, no symbols loaded for d3d11.dll> IDXGIDevice
I dont know what am I doing wrong here.I have included Static libraries(dxgi.lib
d3dx11.lib
d3d11.lib
dxguid.lib
D3DCompiler.lib) and linked correctly the header files and libraries as well..
The error seems to arise from this line
SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)(&backBuffer));
I dont know what to do..It has gotten me really frustrated.
Please do help me out here..I will be very thank full
Thanks
Here is the full code
#include <Windows.h>
#include <windowsx.h>
#include <D3D11.h>
#include <D3DX11.h>
#include <D3DX10.h>
using namespace std;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass);
RECT windowWidth = {0,0, 1000,768};
int WINAPI WinMain(HINSTANCE inst,HINSTANCE previnst,LPSTR cmdLine,int show)
{
// Window Params
HWND hwnd;
WNDCLASSEX exClass;
MSG msg;
// Iniitaliztion
SecureZeroMemory(&hwnd,sizeof(HWND));
SecureZeroMemory(&exClass,sizeof(exClass));
SecureZeroMemory(&msg,sizeof(MSG));
// Directx 11 Functionalities
#pragma region Create the device
D3D_FEATURE_LEVEL featureLevels[4] = {D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 , D3D_FEATURE_LEVEL_10_0 , D3D_FEATURE_LEVEL_9_1};
D3D_FEATURE_LEVEL feature_LEVEL;
ID3D11Device * d3dDevice = 0;
ID3D11DeviceContext * d3dContext = 0;
HRESULT hr = D3D11CreateDevice(0,
D3D_DRIVER_TYPE_HARDWARE,
0,
0, // No flags
featureLevels,4,
D3D11_SDK_VERSION,
&d3dDevice,
&feature_LEVEL,&d3dContext);
if(FAILED(hr))
{
MessageBox(hwnd,L"FAiled TO CREATE DEVICE",L"ERROR",0);
}
#pragma endregion
#pragma region Multisampling
UINT multisampleQuality;
d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM,4,&multisampleQuality);
#pragma endregion
#pragma region DescribeSwapChain
DXGI_SWAP_CHAIN_DESC swapDesc;
// Allocate Mommory
SecureZeroMemory(&swapDesc,sizeof(DXGI_SWAP_CHAIN_DESC));
swapDesc.BufferDesc.Width = 1000;
swapDesc.BufferDesc.Height = 768;
swapDesc.BufferDesc.RefreshRate.Numerator= 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//MSAA
swapDesc.SampleDesc.Count = 4;
swapDesc.SampleDesc.Quality = multisampleQuality;
//BackBuffer
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.BufferCount = 1;
swapDesc.OutputWindow = hwnd;
swapDesc.Windowed = true;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapDesc.Flags = 0;
#pragma endregion
#pragma region CreateSwapChain
#pragma region Obtain DXGIFactory
// DXGIFactory >> DXGIAdaptor >> DXGIDevice
// Get the DXGI device
IDXGIDevice * dxgiDevice = 0;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void**)&dxgiDevice);
// Obtain DXGIAdaptor
IDXGIAdapter * dxgiAdaptor = 0;
dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&dxgiAdaptor);
IDXGIFactory * dxgiFactory = 0;
dxgiAdaptor->GetParent(__uuidof(IDXGIFactory),(void**)&dxgiFactory);
#pragma endregion
IDXGISwapChain * SwapChain = 0;
SecureZeroMemory(&SwapChain,sizeof(IDXGISwapChain));
dxgiFactory->CreateSwapChain(d3dDevice,&swapDesc,&SwapChain);
dxgiAdaptor->Release();
dxgiDevice->Release();
dxgiFactory->Release();
#pragma endregion
#pragma region Create Render Target View
ID3D11RenderTargetView * RenderTarget = 0;
ID3D11Texture2D * backBuffer = 0;
SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)(&backBuffer));
d3dDevice->CreateRenderTargetView(backBuffer,NULL,&RenderTarget);
backBuffer->Release();
#pragma endregion
if(InitWindowClass(inst,show,&hwnd,&exClass))
{
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{
// Update Sequences
}
}
}
return msg.wParam;
}
// Initialize and show the Window
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass)
{
HWND hwnd2 ;
SecureZeroMemory(&hwnd2,sizeof(HWND));
exClass->cbSize = sizeof(WNDCLASSEX);
exClass->hCursor = LoadCursor(0,IDC_ARROW);
exClass->hInstance = hinst;
exClass->lpfnWndProc = WndProc;
exClass->lpszClassName = L"DX_Test";
exClass->lpszMenuName = L"Test";
exClass->hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClassEx(exClass);
AdjustWindowRect(&windowWidth,WS_OVERLAPPEDWINDOW,false);
(*_hwnd) = CreateWindowEx(0,L"DX_Test",L"Test",WS_OVERLAPPEDWINDOW,500,200,windowWidth.left,windowWidth.top,NULL,NULL,hinst,0);
ShowWindow((*_hwnd),shw);
UpdateWindow(*_hwnd);
return true;
}
// Message Loop
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch (msg)
{
case WM_LBUTTONDBLCLK:
MessageBox(hwnd,L"Prressed Button 1",L"Mouse 1",0);
return 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYDOWN:
if(wparam == VK_ESCAPE)
DestroyWindow(hwnd);
return 0;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}

The "error message" you're talking about comes from the VS debugger: all it is telling you is that it doesn't have any debugging symbols for d3d11.dll. In other words this is not your problem - it's a red herring.
To solve the problem, you need some error checking. IDXGISwapChain::GetBuffer returns a HRESULT, which you should check for errors, e.g.:
HRESULT res = SwapChain->GetBuffer(...);
if (!SUCCEEDED(res))
{
std::cerr << "Error getting buffer from swap chain: " << std::hex << res << std::endl;
}
You can then check the result against the values in this set of documentation to find out specifically what the error was.
Note that you should probably do similar things for a lot of your other DirectX calls as well.

Related

LNK2019 DirectX unresolved external symbol; file dxerr.lib

Got a LINK2019 error that I can't figure out. Error code: Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __vsnprintf referenced in function "long __stdcall StringVPrintfWorkerA(char *,unsigned int,unsigned int *,char const *,char *)" (?StringVPrintfWorkerA##YGJPADIPAIPBD0#Z) Direct X C:\Visual Studio Programs\Direct X\Direct X\dxerr.lib(dxerra.obj) 1
main.cpp:
#include <Windows.h>
#include <memory>
#include "BlankDemo.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
LPWSTR cmdLine, int cmdShow)
{
UNREFERENCED_PARAMETER(prevInstance);
UNREFERENCED_PARAMETER(cmdLine);
WNDCLASSEX wndClass = { 0 };
wndClass.cbSize = sizeof(WNDCLASS);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "DX11BookWindowClass";
if (!RegisterClassEx(&wndClass))
return -1;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect(&rc, WS_EX_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowA("DX11BookWindowClass", "BlankWin32Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left,
rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
if (!hwnd)
return -1;
ShowWindow(hwnd, cmdShow);
std::auto_ptr<Dx11DemoBase> demo(new BlankDemo());
// Demo Initialize
bool result = demo->Initialize(hInstance, hwnd);
// Error reporting if there is an issue
if (result == false)
return -1;
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Update and Draw
demo->Update(0.0f);
demo->Render();
}
}
// Demo Shutdown
demo->Shutdown();
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDC;
switch (message)
{
case WM_PAINT:
hDC = BeginPaint(hwnd, &paintStruct);
EndPaint(hwnd, &paintStruct);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
defualt:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
// implementation of the BlankDemo class
BlankDemo::BlankDemo()
{
}
BlankDemo::~BlankDemo()
{
}
bool BlankDemo::LoadContent()
{
return true;
}
void BlankDemo::UnloadContent()
{
}
void BlankDemo::Update(float dt)
{
}
void BlankDemo::Render()
{
if (d3dContext_ == 0)
return;
float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
swapChain_->Present(0, 0);
}
BlankDemo.h file:
#pragma once
#ifndef _BLANK_DEMO_H_
#define _BLANK_DEMO_H_
#include "Dx11DemoBase.h"
class BlankDemo : public Dx11DemoBase
{
public:
BlankDemo();
virtual ~BlankDemo();
bool LoadContent();
void UnloadContent();
void Update(float dt);
void Render();
};
#endif // !_BLANK_DEMO_H_
Dx11DemoBase::Dx11DemoBase() : driverType_(D3D_DRIVER_TYPE_NULL),
featureLevel_(D3D_FEATURE_LEVEL_11_0), d3dDevice_(0), d3dContext_(0),
swapChain_(0), backBufferTarget_(0)
{
}
Dx11DemoBase::~Dx11DemoBase()
{
Shutdown();
}
bool Dx11DemoBase::LoadContent()
{
// Override with demo specifics, if any...
return true;
}
void Dx11DemoBase::UnloadContent()
{
// Override with demo specifics, if any...
}
void Dx11DemoBase::Shutdown()
{
UnloadContent();
if (backBufferTarget_) backBufferTarget_->Release();
if (swapChain_) swapChain_->Release();
if (d3dContext_) d3dContext_->Release();
if (d3dDevice_) d3dDevice_->Release();
d3dDevice_ = 0;
d3dContext_ = 0;
swapChain_ = 0;
backBufferTarget_ = 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
bool Dx11DemoBase::Initialize(HINSTANCE hInstance, HWND hwnd)
{
hInstance_ = hInstance;
hwnd_ = hwnd;
RECT dimensions;
GetClientRect(hwnd, &dimensions);
unsigned int width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = true;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
unsigned int creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT result;
unsigned int driver = 0;
for (driver = 0; driver < totalDriverTypes; ++driver)
{
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0,
creationFlags, featureLevels, totalFeatureLevels, D3D11_SDK_VERSION,
&swapChainDesc, &swapChain_, &d3dDevice_, &featureLevel_, &d3dContext_);
if (SUCCEEDED(result))
{
driverType_ = driverTypes[driver];
break;
}
}
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3d device!");
return false;
}
ID3D11Texture2D* backBufferTexture;
result = swapChain_->GetBuffer(0, _uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
if (FAILED(result))
{
DXTRACE_MSG("Failed to get the swap chain back buffer!");
return false;
}
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, &backBufferTarget_);
if (backBufferTexture)
backBufferTexture->Release();
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the render target view!");
return false;
}
d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, 0);
D3D11_VIEWPORT viewport;
viewport.Width = static_cast<float>(width);
viewport.Height = static_cast<float>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
d3dContext_->RSSetViewports(1, &viewport);
return LoadContent();
}
And lastly, the Dx11DemoBase.h header:
#pragma once
#ifndef _DEMO_BASE_H_
#define _DEMO_BASE_H_
#include <d3d11.h>
#include <D3DX11.h>
#include <dxerr.h>
class Dx11DemoBase
{
public:
Dx11DemoBase();
virtual ~Dx11DemoBase();
bool Initialize(HINSTANCE hInstance, HWND hwnd);
void Shutdown();
virtual bool LoadContent();
virtual void UnloadContent();
virtual void Update(float dt) = 0;
virtual void Render() = 0;
protected:
HINSTANCE hInstance_;
HWND hwnd_;
D3D_DRIVER_TYPE driverType_;
D3D_FEATURE_LEVEL featureLevel_;
ID3D11Device* d3dDevice_;
ID3D11DeviceContext* d3dContext_;
IDXGISwapChain* swapChain_;
ID3D11RenderTargetView* backBufferTarget_;
};
#endif // !_DEMO_BASE_H_
Add legacy_stdio_definitions.lib to Additional dependencies list in the Project properties > Configuration Properties > Linker > Input as recommended in this answer: https://stackoverflow.com/a/34230122/6693304
The legacy DirectX SDK is deprecated, so it hasn't been officially updated since the release of Visual Studio 2010 RTM (June 2010). See Microsoft Docs
This has a few specific implications:
The Windows 8.0 SDK, Windows 8.1 SDK, and Windows 10 SDK all have newer headers than the legacy DirectX SDK where they overlap. You can still make use of it with VS 2012, 2013, 2015, or 2017 but you need to reverse the traditional include/lib path order in the VC++ Directories settings. There are a few other quirks covered at the bottom of this Microsoft Docs topic page. See also The Zombie DirectX SDK.
The DLL import libraries in the legacy DirectX SDK are missing some of the imports that are present in the Windows 8.x or Windows 10 SDK. They generally work fine with all C/C++ compilers because they are fairly standard Win32 without any version-specific CRT references.
Static libraries, however, are not guaranteed to be binary compatible from version to version of the C/C++ compiler. dxguid.lib just has some data in it, so it generally works, but dxerr.lib has actual code. Hence with the major changes in the C/C++ Runtime in VS 2015, it no longer works without link errors.
There are two basic solutions to the dxerr.lib problem:
Build your own copy of the code. It's available here. This is the most robust as it will always match your compiler toolset.
You can add legacy_stdio_definitions.lib, but keep in mind that you are already relying on very out-dated files so you should work to remove/minimize use of the legacy DirectX SDK over time.
Many online tutorials for DirectX 11 and books are outdated w.r.t. to the DirectX SDK and still use d3dx11 which is also deprecated. There are numerous open source replacements available for this functionality. See Living without D3DX.
All that said, this question has already been answered on StackOverflow and would have shown up if you just searched dxerr.

How can I render the images on the monitor (or TV) connected to HDMI port of my computer

I am pretty new to DirectX 10 programming, and I have been trying to do the following with my limited skills..
I am trying to display an Image from one machine on to another output device(Another Monitor/TV) connected via HDMI. I researched on it and came to know that DXGI can be pretty useful for rendering purposes. Moreover while researching further I came across this link here. It does show how to display different images on multiple monitors connected to the main machine but it requires extended display for that.
My requirement is that when I run the code It should render the image on another output device without making it an extended display.
Approcah I am trying is that I am enumerating Video Adapters(which in my case is 1 ) and and then enumerating outputs available which should be two in numbers as I have an HDMI out connected to my PC. But if I do not set extended display it shows only one output available in my enumerated outputs array and if I extend the display it shows two of them.Once I am done with enumerating outputs I want to Render that image on desired output.
As far as i know every video adapter has a port for HDMI connected to it.
I wonder, if there is way I can access that port programatically and could render the image using that port??
Other than MSDN, documentation or explanation of those concepts are rather limited, so any help would be very welcome. Here is some code I have :
// include the basic windows header files and the Direct3D header files
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include<vector>
#include<iostream>
#include <sstream>
#include<dxgi.h>
using namespace std;
// include the Direct3D Library file
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dxgi.lib")
std::vector<IDXGIAdapter*> EnumerateAdapters();
void PrintAdapterInfo(IDXGIAdapter* pAdapter);
std::vector<IDXGIOutput*> EnumerateOutputs(IDXGIAdapter* pAdapter);
void PrintOutputInfo(IDXGIOutput* output);
std::vector<DXGI_MODE_DESC*> GetDisplayModeList(IDXGIOutput* output);
void PrintDisplayModeInfo(DXGI_MODE_DESC* pModeDesc);
// global declarations
IDXGISwapChain *swapchain; // the pointer to the swap chain interface
ID3D11Device *dev; // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon; // the pointer to our Direct3D device context
ID3D11RenderTargetView *backbuffer; // the pointer to our back buffer
IDXGIAdapter *pAdapter;
IDXGIAdapter* adapter = NULL;
IDXGIFactory1* factory = NULL;
HINSTANCE hInstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
HWND hWnd;
std::vector<IDXGIOutput*> outputArray;
int nCmdShow;
// function prototypes
void InitD3D(HWND hWnd); // sets up and initializes Direct3D
void RenderFrame(void); // renders a single frame
void CleanD3D(void); // closes Direct3D and releases memory
void CreateWindowsForOutputs();
void GetAdapter();
void MultiRender();
void CreateSwapChainsAndViews();
std::vector<IDXGIAdapter*> EnumerateAdapters();
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
struct WindowDataContainer
{
//Direct3D 10 stuff per window data
IDXGISwapChain* swapChain;
ID3D11RenderTargetView* renderTargetView;
ID3D11DepthStencilView* depthStencilView;
// window goodies
HWND hWnd;
int width;
int height;
};
std::vector<WindowDataContainer*> WindowsArray;
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
std::cout << "Hello \nworld!"; // Will show a popup
std::vector<IDXGIAdapter*> adapters = EnumerateAdapters();
for(std::vector<IDXGIAdapter*>::iterator itor = adapters.begin(); itor != adapters.end(); ++itor)
{
//PrintAdapterInfo(*itor);
// Get Output info
std::vector<IDXGIOutput*> outputArray = EnumerateOutputs(*itor);
for(std::vector<IDXGIOutput*>::iterator outputItor = outputArray.begin(); outputItor != outputArray.end(); ++outputItor)
{
// PrintOutputInfo(*outputItor);
// Get display mode list
std::vector<DXGI_MODE_DESC*> modeList = GetDisplayModeList(*outputItor);
for(std::vector<DXGI_MODE_DESC*>::iterator modeItor = modeList.begin(); modeItor != modeList.end(); ++modeItor)
{
// PrintDisplayModeInfo(*modeItor);
}
}
CreateWindowsForOutputs();
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message == WM_QUIT)
break;
}
MultiRender();
}
//std::getchar();
// return 0;
}
//std:getchar();
}
std::vector<IDXGIAdapter*> EnumerateAdapters()
{
// Create DXGI factory
IDXGIFactory1* pFactory = NULL;
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory));
if (FAILED(hr))
{
MessageBox(NULL, L"Create DXGI factory failed", L"Error", 0);
}
// Enumerate devices
IDXGIAdapter* pAdapter = NULL;
std::vector<IDXGIAdapter*> vAdapters;
for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i)
{
vAdapters.push_back(pAdapter);
}
if (pFactory)
{
pFactory->Release();
pFactory = NULL;
}
return vAdapters;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void InitD3D(HWND hWnd)
{
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 1; // how many multisamples
scd.SampleDesc.Quality = 0; // multisample quality level
scd.Windowed = TRUE; // windowed/full-screen mode
// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain( NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon);
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
pBackBuffer->Release();
// set the render target as the back buffer
devcon->OMSetRenderTargets(1, &backbuffer, NULL);
// Set the viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 800;
viewport.Height = 600;
devcon->RSSetViewports(1, &viewport);
}
// this is the function used to render a single frame
void RenderFrame(void)
{
// clear the back buffer to a deep blue
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
// do 3D rendering on the back buffer here
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}
// this is the function that cleans up Direct3D and COM
void CleanD3D(void)
{
// close and release all existing COM objects
swapchain->Release();
backbuffer->Release();
dev->Release();
devcon->Release();
}
//Acquiring the outputs on our adapter
std::vector<IDXGIOutput*> EnumerateOutputs(IDXGIAdapter* pAdapter)
{
//std::vector<IDXGIOutput*> outputs;
IDXGIOutput* pOutput = NULL;
for (UINT i = 0; pAdapter->EnumOutputs(i, &pOutput) != DXGI_ERROR_NOT_FOUND; ++i)
{
outputArray.push_back(pOutput);
}
return outputArray;
}
void CreateWindowsForOutputs()
{ // std::vector<IDXGIOutput*> outputArray;
for( int i = 0; i < outputArray.size(); ++i )
{
IDXGIOutput* output = outputArray.at(i);
DXGI_OUTPUT_DESC outputDesc;
output->GetDesc( &outputDesc );
int x = outputDesc.DesktopCoordinates.left;
int y = outputDesc.DesktopCoordinates.top;
int width = outputDesc.DesktopCoordinates.right - x;
int height = outputDesc.DesktopCoordinates.bottom - y;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
RECT wr = {0, 0, 800, 600};
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
// Don't forget to clean this up. And all D3D COM objects.
WindowDataContainer* window = new WindowDataContainer;
window->hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our First Direct3D Program",
WS_OVERLAPPEDWINDOW,
300,
300,
wr.right - wr.left,
wr.bottom - wr.top,
NULL,
NULL,
hInstance,
NULL);
// show the window
ShowWindow( window->hWnd, SW_SHOWDEFAULT );
// InitD3D(hWnd);
CreateSwapChainsAndViews();
// set width and height
window->width = width;
window->height = height;
std::vector<WindowDataContainer*> windowsArray;
// shove it in the std::vector
windowsArray.push_back(window);
//if first window, associate it with DXGI so it can jump in
// when there is something of interest in the message queue
// think fullscreen mode switches etc. MSDN for more info.
// if(i == 0)
// factory->MakeWindowAssociation( window->hWnd, 0 );
}
}
std::vector<DXGI_MODE_DESC*> GetDisplayModeList(IDXGIOutput* output)
{
UINT num = 0;
DXGI_FORMAT format = DXGI_FORMAT_R32G32B32A32_TYPELESS;
UINT flags = DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING;
// Get number of display modes
output->GetDisplayModeList(format, flags, &num, 0);
// Get display mode list
DXGI_MODE_DESC * pDescs = new DXGI_MODE_DESC[num];
output->GetDisplayModeList(format, flags, &num, pDescs);
std::vector<DXGI_MODE_DESC*> displayList;
for(int i = 0; i < num; ++i)
{
displayList.push_back(&pDescs[i]);
}
return displayList;
}
void CreateSwapChainsAndViews()
{
std::vector<WindowDataContainer*> windowsArray;
for( int i = 0; i < windowsArray.size(); i++ )
{
WindowDataContainer* window = windowsArray.at(i);
// get the dxgi device
IDXGIDevice* DXGIDevice = NULL;
dev->QueryInterface( IID_IDXGIDevice, ( void** )&DXGIDevice ); // COM stuff, hopefully you are familiar
// create a swap chain
DXGI_SWAP_CHAIN_DESC swapChainDesc;
// fill it in
WindowDataContainer *p_Window = new WindowDataContainer;
HRESULT hr = factory->CreateSwapChain( DXGIDevice, &swapChainDesc, &p_Window->swapChain );
DXGIDevice->Release();
DXGIDevice = NULL;
// get the backbuffer
ID3D11Texture2D* backBuffer = NULL;
hr = window->swapChain->GetBuffer( 0, IID_ID3D11Texture2D, ( void** )&backBuffer );
// get the backbuffer desc
D3D11_TEXTURE2D_DESC backBufferDesc;
backBuffer->GetDesc( &backBufferDesc );
// create the render target view
D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
// fill it in
dev->CreateRenderTargetView( backBuffer, &RTVDesc, &window->renderTargetView );
backBuffer->Release();
backBuffer = NULL;
// Create depth stencil texture
ID3D11Texture2D* depthStencil = NULL;
D3D11_TEXTURE2D_DESC descDepth;
// fill it in
dev->CreateTexture2D( &descDepth, NULL, &depthStencil );
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
// fill it in
dev->CreateDepthStencilView( depthStencil, &descDSV, &window->depthStencilView );
}
}
void MultiRender( )
{
std::vector<WindowDataContainer*> windowsArray;
// Clear them all
for( int i = 0; i < windowsArray.size(); i++ )
{
WindowDataContainer* window = windowsArray.at(i);
// There is the answer to your second question:
devcon->OMSetRenderTargets( 1, &window->renderTargetView, NULL );
// Don't forget to adjust the viewport, in fullscreen it's not important...
D3D11_VIEWPORT Viewport;
Viewport.TopLeftX = 0;
Viewport.TopLeftY = 0;
Viewport.Width = window->width;
Viewport.Height = window->height;
Viewport.MinDepth = 0.0f;
Viewport.MaxDepth = 1.0f;
devcon->RSSetViewports( 1, &Viewport );
// TO DO: AMAZING STUFF PER WINDOW
}
}
//std::vector<IDXGIOutput*> outputArray; // contains outputs per adapter
void EnumOutputsOnAdapter()
{
IDXGIOutput* output = NULL;
for(int i = 0; DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(i, &output); ++i)
{
// get the description
DXGI_OUTPUT_DESC outputDesc;
HRESULT hr = output->GetDesc( &outputDesc );
outputArray.push_back( output );
}
}
// applicable for multiple ones with little effort
void GetAdapter()
{
// remember, we assume there's only one adapter (example purposes)
for( int i = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters( i, &adapter ); ++i );
{
// get the description of the adapter, assuming no failure
DXGI_ADAPTER_DESC adapterDesc;
HRESULT hr = adapter->GetDesc( &adapterDesc );
// Getting the outputs active on our adapter
EnumOutputsOnAdapter();
}
}

Directx11 Rendering with C++ Not Working

I started to practice rendering with directx11.I had done rendering in directx 9. But DX11 is a pain in the ass.. I couldn't manage to even draw a simple traingle. I dont know what I am doing wrong.
I tried removing depth and stencil buffer but was in vain.
So after brooding over this issue for 2 hours i still can't find the solution.
Can anyone please be kind enough to help me.. Please guys
Thanks
Here is the full code
#include <Windows.h>
#include <windowsx.h>
#include <D3D11.h>
#include <D3DX10math.h>
#include <dxerr.h>
#include <D3DX11.h>
#include <D3DX10.h>
#include "CoreApp.h"
#include "AppTime.h"
using namespace std;
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass);
RECT windowWidth = {0,0, 512,512};
void TW_CALL _Callbak(void * clenddata);
void InitPipeline();
void initGraphics();
ID3D11VertexShader * vshader = 0;
ID3D11PixelShader * pixelShader = 0;
ID3D11Device * d3dDevice = 0;
ID3D11DeviceContext * d3dContext = 0;
#pragma region verticles
struct CVertex
{
float X,Y,Z;
D3DXCOLOR col;
};
namespace Color
{
D3DXCOLOR white (255);
D3DXCOLOR Red ((float)255,0.0,0.0,1.0);
}
#pragma endregion
int WINAPI WinMain(HINSTANCE inst,HINSTANCE previnst,LPSTR cmdLine,int show)
{
// Window Params
HWND hwnd;
WNDCLASSEX exClass;
MSG msg;
GameTime time;
// Iniitaliztion
SecureZeroMemory(&hwnd,sizeof(HWND));
SecureZeroMemory(&exClass,sizeof(exClass));
SecureZeroMemory(&msg,sizeof(MSG));
SecureZeroMemory(&time,sizeof(time));
if(InitWindowClass(inst,show,&hwnd,&exClass))
{
// Directx 11 Functionalities
#pragma region Create the device
D3D_FEATURE_LEVEL feature_LEVEL; // Output feature level
HRESULT hr = D3D11CreateDevice(0,
D3D_DRIVER_TYPE_HARDWARE,
0,
0, // No flags
0,0,
D3D11_SDK_VERSION,
&d3dDevice,
&feature_LEVEL,&d3dContext);
if(FAILED(hr))
{
MessageBox(hwnd,L"Failed TO CREATE DEVICE",L"ERROR",0);
}
#pragma endregion
#pragma region Multisampling
UINT multisampleQuality = 0;
d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM,4,&multisampleQuality);
#pragma endregion
#pragma region DescribeSwapChain
DXGI_SWAP_CHAIN_DESC swapDesc;
// Allocate Mommory
SecureZeroMemory(&swapDesc,sizeof(DXGI_SWAP_CHAIN_DESC));
swapDesc.BufferDesc.Width = 512;
swapDesc.BufferDesc.Height = 512;
swapDesc.BufferDesc.RefreshRate.Numerator= 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//MSAA
swapDesc.SampleDesc.Count = 4;
swapDesc.SampleDesc.Quality = multisampleQuality -1;
//BackBuffer
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.BufferCount = 1;
swapDesc.OutputWindow = hwnd;
swapDesc.Windowed = true;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
#pragma endregion
#pragma region CreateSwapChain
#pragma region Obtain DXGIFactory
// DXGIFactory >> DXGIAdaptor >> DXGIDevice
// Get the DXGI device
IDXGIDevice * dxgiDevice = 0;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice),(void**)&dxgiDevice);
// Obtain DXGIAdaptor
IDXGIAdapter * dxgiAdaptor = 0;
dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&dxgiAdaptor);
IDXGIFactory * dxgiFactory = 0;
dxgiAdaptor->GetParent(__uuidof(IDXGIFactory),(void**)&dxgiFactory);
#pragma endregion
IDXGISwapChain * SwapChain = 0;
if(FAILED(dxgiFactory->CreateSwapChain(d3dDevice,&swapDesc,&SwapChain)))
{
MessageBox(hwnd,L"Failed Creating back buffer",L"Error",0);
}
dxgiFactory->MakeWindowAssociation(hwnd,0);
//Release COMs
dxgiAdaptor->Release();
dxgiDevice->Release();
dxgiFactory->Release();
/*IDXGISwapChain * SwapChain = 0;
if(FAILED(D3D11CreateDeviceAndSwapChain(0,D3D_DRIVER_TYPE_HARDWARE,0,0,0,0,D3D11_SDK_VERSION,&swapDesc,&SwapChain,&d3dDevice,&feature_LEVEL,&d3dContext)))
{
MessageBox(hwnd,L"Failed Creating back buffer and device",L"Error",0);
}*/
#pragma endregion
#pragma region Create Render Target View
ID3D11RenderTargetView * RenderTarget ;
ID3D11Texture2D * backBuffer ;
SecureZeroMemory(&backBuffer,sizeof(ID3D11Texture2D));
SecureZeroMemory(&RenderTarget,sizeof(ID3D11RenderTargetView));
SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(void**)&backBuffer);
d3dDevice->CreateRenderTargetView(backBuffer,NULL,&RenderTarget);
// d3dContext->OM
//Release COM
backBuffer->Release();
#pragma endregion
#pragma region Create Depth Stencil Texture
D3D11_TEXTURE2D_DESC depthDesc;
SecureZeroMemory(&depthDesc,sizeof(depthDesc)); // Allocate Memeory
depthDesc.ArraySize = 1;
//Flags
depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthDesc.CPUAccessFlags = 0;
depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; // Format
// Area
depthDesc.Height = 512;
depthDesc.Width = 512;
// Mipmap and MXAA
depthDesc.MipLevels= 1;
depthDesc.SampleDesc.Count = 4;
depthDesc.SampleDesc.Quality = multisampleQuality -1;
depthDesc.Usage = D3D11_USAGE_DEFAULT;
depthDesc.MiscFlags = 0;
// Create and initialize pointers
ID3D11Texture2D * DepthTexture = 0;
ID3D11DepthStencilView * depthView = 0;
//d3dDevice->CreateTexture2D(&depthDesc,0,&DepthTexture);
// d3dDevice->CreateDepthStencilView(DepthTexture,0,&depthView);
#pragma endregion
#pragma region Bind to Output
d3dContext->OMSetRenderTargets(1,&RenderTarget,NULL); // removed depth buffer for testing but still wont work
#pragma endregion
#pragma region Create ViewPort
D3D11_VIEWPORT viewport;
//Clear mommory
SecureZeroMemory(&viewport,sizeof(viewport));
viewport.Height = 512;
viewport.Width = 512;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
d3dContext->RSSetViewports(1,&viewport);
#pragma endregion
TwInit(ETwGraphAPI::TW_DIRECT3D11,d3dDevice);
TwWindowSize(swapDesc.BufferDesc.Width,swapDesc.BufferDesc.Height);
time.Reset();
InitPipeline();
#pragma region Vertex Buffer Creation
CVertex vertex[3] = {
{0,0,0,Color::white},
{0.5,0,0,Color::white},
{0.25,0.5,0,Color::Red},
};
D3D11_BUFFER_DESC VbufferDesc;
D3D11_SUBRESOURCE_DATA vBufferInit;
SecureZeroMemory(&vertex,sizeof(vertex));
SecureZeroMemory(&VbufferDesc,sizeof(VbufferDesc));
SecureZeroMemory(&vBufferInit,sizeof(vBufferInit));
VbufferDesc.Usage = D3D11_USAGE_DEFAULT;
VbufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
VbufferDesc.ByteWidth = 3* sizeof(CVertex);
VbufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_READ;
VbufferDesc.MiscFlags = 0;
VbufferDesc.StructureByteStride = 0;
vBufferInit.pSysMem = vertex;
ID3D11Buffer * Vbuffer = {0};
d3dDevice->CreateBuffer(&VbufferDesc,&vBufferInit,&Vbuffer);
#pragma endregion
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{
// Update Sequences
// Rendering
d3dContext->ClearRenderTargetView(RenderTarget,D3DXCOLOR(0,0,300,0));
UINT stride = sizeof(CVertex);
UINT offset = 0;
d3dContext->IASetVertexBuffers(0,1,&Vbuffer,&stride,&offset);
d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3dContext->Draw(3,0);
SwapChain->Present(0,0);
}
}
}
return msg.wParam;
}
void InitPipeline()
{
ID3D10Blob * vBuffBlob = 0;
ID3D10Blob * pBuffBlob = 0;
//SecureZeroMemory(&vBuffBlob,sizeof(ID3D10Blob));
//SecureZeroMemory(&pBuffBlob,sizeof(ID3D10Blob));
SecureZeroMemory(&vshader,sizeof(ID3D11VertexShader));
SecureZeroMemory(&pixelShader,sizeof(ID3D11PixelShader));
HRESULT hr = D3DX11CompileFromFile(L"source.shader",0,0,"VShader","vs_4_0",0,0,0,&vBuffBlob,0,0);
D3DX11CompileFromFile(L"source.shader",0,0,"PShader","ps_4_0",0,0,0,&pBuffBlob,0,0);
if(FAILED(hr))
MessageBeep(1);
d3dDevice->CreateVertexShader(vBuffBlob->GetBufferPointer(),vBuffBlob->GetBufferSize(),NULL,&vshader);
d3dDevice->CreatePixelShader(pBuffBlob->GetBufferPointer(),pBuffBlob->GetBufferSize(),NULL,&pixelShader);
D3D11_INPUT_ELEMENT_DESC inp[] = {
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}
};
SecureZeroMemory(inp,sizeof(inp));
ID3D11InputLayout * inputL = 0;
d3dDevice->CreateInputLayout(inp,2,vBuffBlob->GetBufferPointer(),vBuffBlob->GetBufferSize(),&inputL);
d3dContext->IASetInputLayout(inputL);
d3dContext->VSSetShader(vshader,NULL,0);
d3dContext->PSSetShader(pixelShader,0,0);
pBuffBlob->Release();
vBuffBlob->Release();
}
// Initialize and show the Window
bool InitWindowClass(HINSTANCE hinst,int shw,HWND * _hwnd,WNDCLASSEX * exClass)
{
exClass->cbSize = sizeof(WNDCLASSEX);
exClass->hCursor = LoadCursor(0,IDC_ARROW);
exClass->hInstance = hinst;
exClass->lpfnWndProc = WndProc;
exClass->lpszClassName = L"DX_Test";
exClass->lpszMenuName = L"Test";
exClass->hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClassEx(exClass);
AdjustWindowRect(&windowWidth,WS_OVERLAPPEDWINDOW,false);
(*_hwnd) = CreateWindowEx(0,L"DX_Test",L"Test",WS_OVERLAPPEDWINDOW,500,200,windowWidth.right - windowWidth.left,windowWidth.bottom-windowWidth.top,NULL,NULL,hinst,0);
ShowWindow((*_hwnd),shw);
UpdateWindow(*_hwnd);
return true;
}
// Message Loop
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
.....
First off, you're not properly initializing the D3D11_INPUT_ELEMENT_DESC structure. You have:
D3D11_INPUT_ELEMENT_DESC inp[] = {
{"POSITION",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,0},
{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,12}
};
SecureZeroMemory(inp,sizeof(inp));
which partially initializes the structure then completely zeros it. That code snippet should be:
D3D11_INPUT_ELEMENT_DESC inp[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
which gives the full description of the input and how it's laid out in memory.
Second, I'd suggest putting this entire project aside and spending about a week reading through both of the tutorials Chuck has linked, reading as much info on MSDN as possible, and give a good read through the book by Frank D. Luna. A lot of this stuff is addressed in his book, and all of the code is available online, so the book isn't required to learn the API (though it certainly helps).
DirectX 9 was easier to get used to, as the fixed function pipeline helped to organize a lot of this extra work. However, if you used DirectX 9.0c and Shader Model 2.x/3, a lot of this code is very similar, and is now required as there is no longer a fixed function pipeline in D3D.

OpenGL context creation never chooses pixel format

I'm trying to create an OpenGL context inside a Win32 window for a library I'm writing. I've boiled it down to a small example which will compile to help debug it. For some reason, it never chooses a pixel format properly. Here's the code:
#include <iostream>
#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/wglew.h>
HWND handle;
HDC deviceContext;
HGLRC context;
int resolutionX = 1280;
int resolutionY = 720;
std::string title = "Test Window";
LRESULT CALLBACK eventCallback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int main()
{
// Register the window class
WNDCLASSA windowClass;
windowClass.style = 0;
windowClass.lpfnWndProc = &eventCallback;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = GetModuleHandle(nullptr);
windowClass.hIcon = nullptr;
windowClass.hCursor = nullptr;
windowClass.hbrBackground = nullptr;
windowClass.lpszMenuName = nullptr;
windowClass.lpszClassName = "Test_Window";
RegisterClassA(&windowClass);
// Compute position and size
HDC screenDC = GetDC(nullptr);
int left = (GetDeviceCaps(screenDC, HORZRES) - static_cast<int>(resolutionX)) / 2;
int top = (GetDeviceCaps(screenDC, VERTRES) - static_cast<int>(resolutionY)) / 2;
int width = resolutionX;
int height = resolutionY;
ReleaseDC(nullptr, screenDC);
// Set window style
DWORD win32Style = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_SYSMENU;
// In windowed mode, adjust width and height so that window will have the requested client area
RECT rectangle = {0, 0, width, height};
AdjustWindowRect(&rectangle, win32Style, false);
width = rectangle.right - rectangle.left;
height = rectangle.bottom - rectangle.top;
// Create the window
handle = CreateWindowA("Test_Window", title.c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(nullptr), nullptr);
if(handle == NULL)
{
std::cout << "Failed to create window" << std::endl;
return 1;
}
// Setup a pixel format descriptor from the rendering settings
PIXELFORMATDESCRIPTOR descriptor;
ZeroMemory(&descriptor, sizeof(descriptor));
descriptor.nSize = sizeof(descriptor);
descriptor.nVersion = 1;
descriptor.iLayerType = PFD_MAIN_PLANE;
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
descriptor.iPixelType = PFD_TYPE_RGBA;
descriptor.cColorBits = static_cast<BYTE>(32);
descriptor.cDepthBits = static_cast<BYTE>(24);
descriptor.cStencilBits = static_cast<BYTE>(8);
descriptor.cAlphaBits = 8;
// Get the pixel format that best matches our requirements
int bestFormat = ChoosePixelFormat(deviceContext, &descriptor);
if(bestFormat == 0)
{
std::cout << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
return 1;
}
// Extract the depth and stencil bits from the chosen format
PIXELFORMATDESCRIPTOR actualFormat;
actualFormat.nSize = sizeof(actualFormat);
actualFormat.nVersion = 1;
DescribePixelFormat(deviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
// Set the chosen pixel format
if(!SetPixelFormat(deviceContext, bestFormat, &actualFormat))
{
std::cout << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
return 1;
}
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
if(wglCreateContextAttribsARB)
{
int attributes[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(3),
WGL_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(0),
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0, 0
};
context = wglCreateContextAttribsARB(deviceContext, nullptr, attributes);
}
if(!context)
{
context = wglCreateContext(deviceContext);
if(!context)
{
std::cout << "Failed to create the OpenGL context" << std::endl;
return 1;
}
}
// Destroy the OpenGL context
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(context);
// Destroy the device context
ReleaseDC(handle, deviceContext);
// Destroy the window handle
DestroyWindow(handle);
// Unregister the window
UnregisterClassA("Test_Window", GetModuleHandle(nullptr));
std::cout << "Window created" << std::endl;
return 0;
}
LRESULT CALLBACK eventCallback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Associate handle and Window instance when the creation message is received
if(message == WM_CREATE)
{
LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
// Set as the "user data" parameter of the window
SetWindowLongPtr(hwnd, GWLP_USERDATA, window);
}
return DefWindowProcA(hwnd, message, wParam, lParam);
}
You never initialize deviceContext, which means that it will have a garbage value. If you call GetLastError after trying ChoosePixelFormat, I imagine that you'll find that it's telling you that you have an invalid handle.
wglGetProcAddress needs a valid OpenGL context being created and bound to yield a sensible result. Which means that in order to use wglCreateContextAttribsARB you first have to create an intermediary helper OpenGL context that gives you access to that function.
Update
As it happens I recently wrote some small helper to deal with this. Available under the terms of the MIT license at https://github.com/datenwolf/wglarb
Try to add this on the initialization of pixel format descriptor:
descriptor.cRedBits = 8;
descriptor.cGreenBits = 8;
descriptor.cBlueBits = 8;

fatal error C1014: too many include files : depth = 1024

I have no idea what this means. But here is the code that it supposely is happening in.
//=======================================================================================
// d3dApp.cpp by Frank Luna (C) 2008 All Rights Reserved.
//=======================================================================================
#include "d3dApp.h"
#include <stream>
LRESULT CALLBACK
MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static D3DApp* app = 0;
switch( msg )
{
case WM_CREATE:
{
// Get the 'this' pointer we passed to CreateWindow via the lpParam parameter.
CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
app = (D3DApp*)cs->lpCreateParams;
return 0;
}
}
// Don't start processing messages until after WM_CREATE.
if( app )
return app->msgProc(msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
D3DApp::D3DApp(HINSTANCE hInstance)
{
mhAppInst = hInstance;
mhMainWnd = 0;
mAppPaused = false;
mMinimized = false;
mMaximized = false;
mResizing = false;
mFrameStats = L"";
md3dDevice = 0;
mSwapChain = 0;
mDepthStencilBuffer = 0;
mRenderTargetView = 0;
mDepthStencilView = 0;
mFont = 0;
mMainWndCaption = L"D3D10 Application";
md3dDriverType = D3D10_DRIVER_TYPE_HARDWARE;
mClearColor = D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f);
mClientWidth = 800;
mClientHeight = 600;
}
D3DApp::~D3DApp()
{
ReleaseCOM(mRenderTargetView);
ReleaseCOM(mDepthStencilView);
ReleaseCOM(mSwapChain);
ReleaseCOM(mDepthStencilBuffer);
ReleaseCOM(md3dDevice);
ReleaseCOM(mFont);
}
HINSTANCE D3DApp::getAppInst()
{
return mhAppInst;
}
HWND D3DApp::getMainWnd()
{
return mhMainWnd;
}
int D3DApp::run()
{
MSG msg = {0};
mTimer.reset();
while(msg.message != WM_QUIT)
{
// If there are Window messages then process them.
if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// Otherwise, do animation/game stuff.
else
{
mTimer.tick();
if( !mAppPaused )
updateScene(mTimer.getDeltaTime());
else
Sleep(50);
drawScene();
}
}
return (int)msg.wParam;
}
void D3DApp::initApp()
{
initMainWindow();
initDirect3D();
D3DX10_FONT_DESC fontDesc;
fontDesc.Height = 24;
fontDesc.Width = 0;
fontDesc.Weight = 0;
fontDesc.MipLevels = 1;
fontDesc.Italic = false;
fontDesc.CharSet = DEFAULT_CHARSET;
fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
fontDesc.Quality = DEFAULT_QUALITY;
fontDesc.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
wcscpy(fontDesc.FaceName, L"Times New Roman");
D3DX10CreateFontIndirect(md3dDevice, &fontDesc, &mFont);
}
void D3DApp::onResize()
{
// Release the old views, as they hold references to the buffers we
// will be destroying. Also release the old depth/stencil buffer.
ReleaseCOM(mRenderTargetView);
ReleaseCOM(mDepthStencilView);
ReleaseCOM(mDepthStencilBuffer);
// Resize the swap chain and recreate the render target view.
HR(mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
ID3D10Texture2D* backBuffer;
HR(mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer)));
HR(md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView));
ReleaseCOM(backBuffer);
// Create the depth/stencil buffer and view.
D3D10_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = mClientWidth;
depthStencilDesc.Height = mClientHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1; // multisampling must match
depthStencilDesc.SampleDesc.Quality = 0; // swap chain values.
depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
HR(md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
HR(md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView));
// Bind the render target view and depth/stencil view to the pipeline.
md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
// Set the viewport transform.
D3D10_VIEWPORT vp;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = mClientWidth;
vp.Height = mClientHeight;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
md3dDevice->RSSetViewports(1, &vp);
}
void D3DApp::updateScene(float dt)
{
// Code computes the average frames per second, and also the
// average time it takes to render one frame.
static int frameCnt = 0;
static float t_base = 0.0f;
frameCnt++;
// Compute averages over one second period.
if( (mTimer.getGameTime() - t_base) >= 1.0f )
{
float fps = (float)frameCnt; // fps = frameCnt / 1
float mspf = 1000.0f / fps;
std::wostringstream outs;
outs.precision(6);
outs << L"FPS: " << fps << L"\n"
<< "Milliseconds: Per Frame: " << mspf;
mFrameStats = outs.str();
// Reset for next average.
frameCnt = 0;
t_base += 1.0f;
}
}
void D3DApp::drawScene()
{
md3dDevice->ClearRenderTargetView(mRenderTargetView, mClearColor);
md3dDevice->ClearDepthStencilView(mDepthStencilView, D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL, 1.0f, 0);
}
LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
// WM_ACTIVATE is sent when the window is activated or deactivated.
// We pause the game when the window is deactivated and unpause it
// when it becomes active.
case WM_ACTIVATE:
if( LOWORD(wParam) == WA_INACTIVE )
{
mAppPaused = true;
mTimer.stop();
}
else
{
mAppPaused = false;
mTimer.start();
}
return 0;
// WM_SIZE is sent when the user resizes the window.
case WM_SIZE:
// Save the new client area dimensions.
mClientWidth = LOWORD(lParam);
mClientHeight = HIWORD(lParam);
if( md3dDevice )
{
if( wParam == SIZE_MINIMIZED )
{
mAppPaused = true;
mMinimized = true;
mMaximized = false;
}
else if( wParam == SIZE_MAXIMIZED )
{
mAppPaused = false;
mMinimized = false;
mMaximized = true;
onResize();
}
else if( wParam == SIZE_RESTORED )
{
// Restoring from minimized state?
if( mMinimized )
{
mAppPaused = false;
mMinimized = false;
onResize();
}
// Restoring from maximized state?
else if( mMaximized )
{
mAppPaused = false;
mMaximized = false;
onResize();
}
else if( mResizing )
{
// If user is dragging the resize bars, we do not resize
// the buffers here because as the user continuously
// drags the resize bars, a stream of WM_SIZE messages are
// sent to the window, and it would be pointless (and slow)
// to resize for each WM_SIZE message received from dragging
// the resize bars. So instead, we reset after the user is
// done resizing the window and releases the resize bars, which
// sends a WM_EXITSIZEMOVE message.
}
else // API call such as SetWindowPos or mSwapChain->SetFullscreenState.
{
onResize();
}
}
}
return 0;
// WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
case WM_ENTERSIZEMOVE:
mAppPaused = true;
mResizing = true;
mTimer.stop();
return 0;
// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
// Here we reset everything based on the new window dimensions.
case WM_EXITSIZEMOVE:
mAppPaused = false;
mResizing = false;
mTimer.start();
onResize();
return 0;
// WM_DESTROY is sent when the window is being destroyed.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
// The WM_MENUCHAR message is sent when a menu is active and the user presses
// a key that does not correspond to any mnemonic or accelerator key.
case WM_MENUCHAR:
// Don't beep when we alt-enter.
return MAKELRESULT(0, MNC_CLOSE);
// Catch this message so to prevent the window from becoming too small.
case WM_GETMINMAXINFO:
((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200;
return 0;
}
return DefWindowProc(mhMainWnd, msg, wParam, lParam);
}
void D3DApp::initMainWindow()
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = mhAppInst;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = L"D3DWndClassName";
if( !RegisterClass(&wc) )
{
MessageBox(0, L"RegisterClass FAILED", 0, 0);
PostQuitMessage(0);
}
// Compute window rectangle dimensions based on requested client area dimensions.
RECT R = { 0, 0, mClientWidth, mClientHeight };
AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
int width = R.right - R.left;
int height = R.bottom - R.top;
mhMainWnd = CreateWindow(L"D3DWndClassName", mMainWndCaption.c_str(),
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInst, this);
if( !mhMainWnd )
{
MessageBox(0, L"CreateWindow FAILED", 0, 0);
PostQuitMessage(0);
}
ShowWindow(mhMainWnd, SW_SHOW);
UpdateWindow(mhMainWnd);
}
void D3DApp::initDirect3D()
{
// Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain.
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = mClientWidth;
sd.BufferDesc.Height = mClientHeight;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// No multisampling.
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = mhMainWnd;
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
// Create the device.
UINT createDeviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
HR( D3D10CreateDeviceAndSwapChain(
0, //default adapter
md3dDriverType,
0, // no software device
createDeviceFlags,
D3D10_SDK_VERSION,
&sd,
&mSwapChain,
&md3dDevice) );
// The remaining steps that need to be carried out for d3d creation
// also need to be executed every time the window is resized. So
// just call the onResize method here to avoid code duplication.
onResize();
}
Some where an include file that has no include guard is including itself (directly or indirectly).
Use /showIncludes ("Configuration Properties/C/C++/Advanced/Show Includes" in the IDE's project options) to get help with this.
The easiest way to fix your problem is at the top of all of your header files add:
#pragma once
Do this always everytime you make a header file in C++. If your compiler doesn't support the above (I seriously doubt anyone uses a compiler that doesn't support it, Visual Studio which you use does) then you can use include guards.
The #pragma once directive ensures that your includes will only be included once.
You will get the error you got if you have the following situation:
file: a.h
#include "b.h"
file: b.h
#include "a.h"
Then in your main app you include one of the 2 header files.
You can fix your situation by doing the following:
file: a.h
#pragma once
#include "b.h"
file: b.h
#pragma once
#include "a.h"
std::stringstream is in the sstream header, so:
#include <sstream>
I think that your solution was recursive inclusion as Michael Burr stated, but for the record it can also happen with only correct inclusions, when the hierarchy is too deep.
For instance, if you have 1024 files, each one including only the next one.
I just encountered this issue when I accidentally had:
header/foo.hpp
source/foo.hpp
Rather than:
header/foo.hpp
source/foo.cpp
Thus causing:
#include "foo.hpp"
To cause this error. Thought I'd add this answer as I was feeling stumped: no deep include chain, no forgotten header guard, I wasn't doing #include "foo.cpp"... except I was and didn't realise it.
For me, this was caused because I copied the contents of a cpp into the header that was being referenced in the cpp.