views:

50

answers:

1

I have an windowless IViewObject object.

I want to call its Draw function to render into Opengl PBO memory (alternatively OleDraw is simpler).

Right now i first create an HBITMAP using CreateDIBSection (which allocates its own memory) and then copy from this into my PBO memory. However, I'd like to avoid this extra copy. I believe this should be possible in theory as mapped PBOs live in page-locked memory.

This is what I do today simplified:

hdc = CreateCompatibleDC(nullptr); // Get current DC
HBITMAP bitmap = CreateDIBSection(... hdc, &bitmap_data_...); // Create Bitmap
SelectObject(hdc, bitmap);
m_spViewObject->Draw(... hdc ...); // IViewObject->Draw to bitmap
memcpy(pbo_ptr, bitmap_data_, size);

My question is if its possible to have the Draw function to somehow draw to memory which i have specified (in this case the PBO) instead of memory allocated by the win32 api (CreateDIBSection)?

One way might be if it is possible to create a device independent bitmap from user specified memory? However, I have found no function that does this.

+4  A: 

What you're trying to do is very logical IMHO. However unfortunately AFAIK there's no conventional way to do this.

According to WinAPI DIB sections either allocate their own memory or work with the file mapping. OTOH OpenGL manages its memory in its own way. There exists an option to create a DIB from any memory block, but it's for video drivers only, not accessible to the user-mode applications.

There's actually a very complex possibility to avoid this extra-copy. You may create a virtual video driver (not to be confused with mirror video driver), obtain its HDC. Then in you 'custom' way tell it where it should draw (via Escape). And then you may pass this HDC to whatever you want to do the drawing, your virtual video driver will draw directly on the memory you want.

Moreover, to do the actual drawing you will be able to use the OS functions. Wrap your memory by GDI-recognizable bitmap (EngCreateBitmap), and draw on it using OS (EngXXXX), so that you'll have to implement only the minimum functionality in your driver.

However this is a driver development anyway. I believe that copying a memory block is fast enough (comparison to the actual drawing), so that you can leave your code as-is.

valdo
Excellent answer. And I do agree that the extra copy is no bottleneck. However, I still think it would be fun to solve this problem. Do you have any suggestions on resources that could get me started on writing such a "driver"?
ronag
Just one more question. Is it necessary to put these driver dlls in the system32 directory, or can I have them in the application directory?
ronag
Well, honestly speaking I don't know what do advise you. Once I've written a (sort of) video driver, and I've collected the information "By pieces" from MSDN. It's a good to start from reading the "mirror" video driver source code, provided with the WDK (former DDK). Also try searching web for `DrvEnableDriver`, `DrvEnableSurface` and etc.
valdo
About the video driver DLL. Yes, it should reside within the system32 directory. At least the 'logical' driver part, the DLL file. (there's also the corresponding SYS file, so-called miniport driver). There're however "indirect" techniques to work this around, but this is another driver development and hooking into OS internals
valdo