Direct3D 11 FreePascal Create Device - directx-11

I have just want to test direct3d 11, but it crashes at
D3D11CreateDeviceAndSwapChain call with error message project raise exception class 'external: ?' at address. Video Card supports Directx 11.
What is wrong?
D3D11CreateDeviceAndSwapChain( nil, g_driverType, 0, createDeviceFlags, #featureLevels, Length(featureLevels), D3D11_SDK_VERSION, sd, g_pSwapChain, g_pd3dDevice, g_featureLevel, g_pImmediateContext );

Related

What's the etymology behind type name ID3D10Blob for direct x shaders?

What's the etymology behind type name ID3D10Blob for direct x shaders?
I'm reading http://www.directxtutorial.com/Lesson.aspx?lessonid=11-4-5 and trying to reason about the naming conventions in windows.
I see ID3D10Blob as (I)(D3D10)(Blob).
I = interface?
D3D10 = direct3d 10?
Blob = ?
I've seen "Binary large object" online for Blob, but I'm not sure if that has the same meaning in this context.
What does the blob term mean?
TL;DR: It's just a simple ref-counted container for a variable-length blob of binary data used by the D3DCompiler COM interfaces.
The HLSL compiler produces a 'shader blob' which is just an opaque binary object. It has a size and data. It could be really anything, but in the world of "COM" objects, it was implemented for Windows Vista as ID3D10Blob with the introduction of Direct3D 10.
Historically, Direct3D 9 and earlier had a 'fixed-function' rendering pipeline which means you could use it without HLSL shaders. For Direct3D 10, the 'fixed-function' was removed, so HLSL was required to use it at all. Therefore, a version of the Direct3D HLSL Compiler was added to the OS.
The ID3DBlob interface is what's used for Direct3D 11 or Direct3D 12, but if you look at it closely, it's the same thing.
typedef ID3D10Blob ID3DBlob;
The Direct3D API itself actually doesn't use this specific 'blob' interface. In a C++ STL world, you could use std::vector<uint8_t> as a shader blob:
inline std::vector<uint8_t> ReadData(_In_z_ const wchar_t* name)
{
std::ifstream inFile(name, std::ios::in | std::ios::binary | std::ios::ate);
if (!inFile)
throw std::exception("ReadData");
std::streampos len = inFile.tellg();
if (!inFile)
throw std::exception("ReadData");
std::vector<uint8_t> blob;
blob.resize(size_t(len));
inFile.seekg(0, std::ios::beg);
if (!inFile)
throw std::exception("ReadData");
inFile.read(reinterpret_cast<char*>(blob.data()), len);
if (!inFile)
throw std::exception("ReadData");
inFile.close();
return blob;
}
…
auto vertexShaderBlob = ReadData(L"VertexShader.cso");
ThrowIfFailed(
device->CreateVertexShader(vertexShaderBlob.data(), vertexShaderBlob.size(),
nullptr, m_spVertexShader.ReleaseAndGetAddressOf()));
auto pixelShaderBlob = ReadData(L"PixelShader.cso");
ThrowIfFailed(
device->CreatePixelShader(pixelShaderBlob.data(), pixelShaderBlob.size(),
nullptr, m_spPixelShader.ReleaseAndGetAddressOf()));
See Microsoft Docs and this blog post.

How can I load the same icon as used by MessageBox on Windows 10?

On Windows 10 calling LoadIcon asking for the standard icon IDI_INFORMATION yields this icon:
On the other hand, calling MessageBox passing IDI_INFORMATION produces a dialog that uses this icon:
How can I obtain the second icon, if the obvious call to LoadIcon does not do so?
This feels like a bug in user32.dll but Windows 8 has the same issue so I guess Microsoft doesn't care.
You can get the flat icon used by MessageBox by calling SHGetStockIconInfo:
SHSTOCKICONINFO sii;
sii.cbSize = sizeof(sii);
if (SUCCEEDED(SHGetStockIconInfo(SIID_INFO, SHGSI_ICON|SHGSI_LARGEICON, &sii)))
{
// Use sii.hIcon here...
DestroyIcon(sii.hIcon);
}
SHGetStockIconInfo is the documented way to get icons used in the Windows UI on Vista and later. Most of the icons come from imageres.dll but you should not assume that this is the case...
we can try next code for test/demo
MSGBOXPARAMSW mbi = {
sizeof(mbi),
HWND_DESKTOP,
NULL,
L"lpszText",
L"lpszCaption",
MB_USERICON,
IDI_INFORMATION
};
MessageBoxIndirectW(&mbi);
if (HMODULE hmodImageRes = LoadLibraryEx(L"imageres", 0, LOAD_LIBRARY_AS_DATAFILE))
{
mbi.hInstance = hmodImageRes;
mbi.lpszIcon = MAKEINTRESOURCE(81);
MessageBoxIndirectW(&mbi);
FreeLibrary(hmodImageRes);
}
first message box use standard IDI_INFORMATION icon
when second the same icon on windows 7, and on windows 8.1 and windows 10.
are MAKEINTRESOURCE(81) from imageres.dll somehow documented and be stable - i doubt
so obtain the second icon you can by LoadIcon(hmodImageRes, MAKEINTRESOURCE(81)) where HMODULE hmodImageRes = LoadLibraryEx(L"imageres", 0, LOAD_LIBRARY_AS_DATAFILE) or simply LoadLibrary(L"imageres")

CGBitmapContextCreate: unsupported parameter combination

I'm getting this error when creating a bitmap context:
CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 24 bits/pixel; 3-component color space; kCGImageAlphaNone; 7936 bytes/row.
Here's the code (note that the context is based on the parameters of an existing CGImage:
context = CGBitmapContextCreate(NULL,
(int)pi.bufferSizeRequired.width,
(int)pi.bufferSizeRequired.height,
CGImageGetBitsPerComponent(imageRef),
0,
CGImageGetColorSpace(imageRef),
CGImageGetBitmapInfo(imageRef));
Width is 2626, height is 3981. I've leaving bytesPerRow at zero so that it gets calculated automatically for me, and it's chosen 7936 of its own accord.
So, where on Earth is the inconsistency? It's driving me nuts.
For reasons that I don't understand I solved this by setting the BitmapInfo parameter to kCGImageAlphaNoneSkipLast.
CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 24 bits/pixel; 3-component color space; kCGImageAlphaNone; 7936 bytes/row.
In the Quartz 2D Programming documentation is a list of the supported pixel formats. The 8/3/24 combination is not supported but 8/3/32 is, independent of using alpha or not.
Heinrich gave you a good background to the answer. Just thought I'd offer up my specific case, as an alternative to tarmes' answer. The problem with that answer is that it doesn't solve the issue if you want an alpha channel present. I was using a category called UIImage+Alpha by Trevor Harmon when I encountered this issue. In the code I found this comment:
// The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
Now this hardcoded fix was in one of the methods calling CGBitmapContextCreate, but not the one following it. So for me it was simply a matter of following the author's own advice to fix the problem in one of his other methods ;)
Clearly some part of the CGBitmapInfo is not getting passed correctly from the image in question, though why I don't know.
So use these constants in the bitmapInfo if you're working with the alpha channel: kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst
Otherwise, I'd just like to point out it's a really useful class if you're dealing with aliasing issues!
(Also, worth mentioning this problem only turned up in Xcode 6....)
I'm not sure it would help anybody or not, I just run into the similar issue and try anyway as suggested but no luck.
My issue is:
CCLabelTTF *header_txt = [CCLabelTTF
labelWithString:header
fontName:fontname fontSize:header_fontsize
dimensions:CGSizeMake(header_fontsize*9, txt_h)
hAlignment:kCCTextAlignmentLeft
vAlignment:kCCVerticalTextAlignmentCenter];
With Error:
< Error >: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 8 bits/pixel; 1-component color space; kCGImageAlphaNone; 2147483648 bytes/row.
Then I found a mistake is that header_fontsize is not assigned any values (because I mistake fontsize with header_fontsize). The error lies here: dimensions:CGSizeMake(header_fontsize*9, txt_h) with header_fontsize unassigned any value (it's not 0, assign header_fontsize = 0still ok); reassign a value to header_fontsize fixed the issue.
Hope this will help someone in similar case, such as Sprite case.
Some pixel formats are just unsupported.
You can check in advance if any image is supported with:
extension CGImage {
public var hasCGContextSupportedPixelFormat: Bool {
guard let colorSpace = self.colorSpace else {
return false
}
#if os(iOS) || os(watchOS) || os(tvOS)
let iOS = true
#else
let iOS = false
#endif
#if os(OSX)
let macOS = true
#else
let macOS = false
#endif
switch (colorSpace.model, bitsPerPixel, bitsPerComponent, alphaInfo, bitmapInfo.contains(.floatComponents)) {
case (.unknown, 8, 8, .alphaOnly, _):
return macOS || iOS
case (.monochrome, 8, 8, .none, _):
return macOS || iOS
case (.monochrome, 8, 8, .alphaOnly, _):
return macOS || iOS
case (.monochrome, 16, 16, .none, _):
return macOS
case (.monochrome, 32, 32, .none, true):
return macOS
case (.rgb, 16, 5, .noneSkipFirst, _):
return macOS || iOS
case (.rgb, 32, 8, .noneSkipFirst, _):
return macOS || iOS
case (.rgb, 32, 8, .noneSkipLast, _):
return macOS || iOS
case (.rgb, 32, 8, .premultipliedFirst, _):
return macOS || iOS
case (.rgb, 32, 8, .premultipliedLast, _):
return macOS || iOS
case (.rgb, 64, 16, .premultipliedLast, _):
return macOS
case (.rgb, 64, 16, .noneSkipLast, _):
return macOS
case (.rgb, 128, 32, .noneSkipLast, true):
return macOS
case (.rgb, 128, 32, .premultipliedLast, true):
return macOS
case (.cmyk, 32, 8, .none, _):
return macOS
case (.cmyk, 64, 16, .none, _):
return macOS
case (.cmyk, 128, 32, .none, true):
return macOS
default:
return false
}
}
}
See https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html for more information (and the list of supported pixel formats)

Qt: QPainter + GDI in the same widget?

I'm trying to use the method described here to use a QPainter and GDI calls on the same widget.
Unfortunately this tutorial seem to have been written on an earlier version of Qt and now it does not work.
I set the WA_PaintOnScreen flag and reimplement paintEngine() to return NULL.
Then on the paintEvent() I create a QPainter, use it and then use some GDI calls to paint a bitmap. The GDI calls work fine but the QPainter does nothing. I get the following error on the console:
QPainter::begin: Paint device returned engine == 0, type: 1
Is this simply not supported anymore? how can I do it?
I've also tried creating an additional widget on top of the GDI-painting widget but that didn't go well as well since the top widget appears black and blocks the GDI widget.
I got this working in QT 4.7-beta 2 as follows
In the constructor call setAttribute(Qt::WA_PaintOnScreen,true);
Do NOT reimplement paintEngine() to return NULL;
Use the following code in the paintEvent();
QPainter painter(this);
HDC hdc = painter.paintEngine()->getDC(); // THIS IS THE CRITICAL STEP!
HWND hwnd = winID();
// From this point on it is all regular GDI
QString text("Test GDI Paint");
RECT rect;
GetClientRect(hwnd, &rect);
HBRUSH hbrRed = CreateSolidBrush(RGB(255,0,0));
FillRect(hdc, &rect, hbrRed);
HBRUSH hbrBlue = CreateSolidBrush(RGB(40,40,255));
HPEN bpenGreen = CreatePen(PS_SOLID, 4, RGB(0,255,0));
SelectObject(hdc,bpenGreen);
SelectObject(hdc,hbrBlue);
Ellipse(hdc,10,10,rect.right-20,rect.bottom-20);
SetTextAlign(hdc, TA_CENTER | TA_BASELINE);
TextOutW(hdc, width() / 2, height() / 2, text.utf16(), text.size());
ReleaseDC(hwnd, hdc);
This worked with Qt 4.0 and 4.1, but stopped working in either 4.2 or 4.3, when Trolltech reimplemented the Windows paint engine. In the second edition of the Qt 4 book, we added the sentence:
"For this to work, we must also reimplement QPaintDevice::paintEngine() to return a null pointer and set the Qt::WA_PaintOnScreen attribute in the widget's constructor."
I haven't tested it using later versions of Qt (I'm no longer at Trolltech/Nokia and have no Windows machine) but I hope it will still work.

StretchBlt fails when printing

I have a chart (in bitmap format) that I'm trying to render to a printer using StretchBlt. When drawing to the screen, StretchBlt works fine. When drawing to a CutePDF printer, it returns 0, sets the last error to ERROR_INVALID_HANDLE, and works anyway. When drawing to a PDF995 printer or a physical HP printer, it returns 0, sets the last error to ERROR_INVALID_HANDLE, and fails to draw anything.
What would cause StretchBlt to fail for certain devices? I've verified that the source bitmap is a DIB and that the destination supports StretchBlt by calling GetDeviceCaps.
Here's my code, in case it's relevant: (It's written in C++Builder, so it uses Delphi's VCL; TCanvas wraps an HDC, and TBitmap wraps an HBITMAP. VCL provides its own StretchDraw function which does not support HALFTONE; I'm getting the same problems with it.)
void PrettyStretchDraw(TCanvas *dest, const TRect& rect, TGraphic *source)
{
if (dynamic_cast<Graphics::TBitmap*>(source) && !source->Transparent) {
POINT pt;
GetBrushOrgEx(dest->Handle, &pt);
SetStretchBltMode(dest->Handle, HALFTONE);
SetBrushOrgEx(dest->Handle, pt.x, pt.y, NULL);
StretchBlt(
dest->Handle,
rect.Left,
rect.Top,
rect.Width(),
rect.Height(),
dynamic_cast<Graphics::TBitmap*>(source)->Canvas->Handle,
0,
0,
source->Width,
source->Height,
SRCCOPY);
} else {
DrawItSomeOtherWay(dest, rect, source);
}
}
StretchBlt is broken on some printer drivers (PDF995 is notable example).
I once encontered this error happening on Windows 2003 Server only (it worked on XP).
Try to reproduce the problem on other OS, and it it does not, consider it OS specific and use StretchDIBits instead on this OS.

Resources