IViewObjectEx->Draw to PBO

I have several activex com objects running in their own threads, IViewObjectEx.

Right now i render to memory from this object using HBITMAP.

Simplified:
hdc = CreateCompatibleDC(nullptr); // Get current DC
HBITMAP bitmap = CreateDIBSection(… hdc …); // Create Bitmap
SelectObject(hdc, bitmap);
m_spViewObject->Draw(… hdc …); // IViewObjectEx->Draw to bitmap

This works well. However I’d like to render directly to a PBO, instead of first to a HBITMAP and then copying to a PBO like I’m doing now.

Is this possible?

It should be possible. Create HBITMAP by CreateBitmapIndirect() with PBO data.

Could you please explain? I don’t see how I would use that.

create PBO, map it to get memory pointer, create BITMAP structure (set bmBits to PBO memory) and call CreateBitmapIndirect to get HBITMAP.

I also found these function:

wglGetPbufferDCARB()
wglCreateContext()

Still looking into them.

Could work. Will try it during next week.

Still no success. It runs but it’s all black.

Any ideas as to what might be wrong?


struct bitmap_frame::implementation : boost::noncopyable
{
        // Works
	implementation(size_t width, size_t height) 
	: size_(width*height*4), width_(width), height_(height), 
           hdc_(CreateCompatibleDC(nullptr)), bitmap_handle_(nullptr)
	{	
		if(hdc_ == nullptr)
			throw std::bad_alloc();
		
		BITMAPINFO bitmapInfo;
		bitmapInfo.bmiHeader.biBitCount = 32;
		bitmapInfo.bmiHeader.biClrImportant = 0;
		bitmapInfo.bmiHeader.biClrUsed = 0;
		bitmapInfo.bmiHeader.biCompression = BI_RGB;
	#pragma warning(disable:4146)
		bitmapInfo.bmiHeader.biHeight = -height;
	#pragma warning(default:4146)
		bitmapInfo.bmiHeader.biPlanes = 1;
		bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);
		bitmapInfo.bmiHeader.biWidth = width;
		bitmapInfo.bmiHeader.biSizeImage = 0;
		bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
		bitmapInfo.bmiHeader.biYPelsPerMeter = 0;

		bitmap_handle_ = CreateDIBSection(hdc_, &bitmapInfo, 
                                                   DIB_RGB_COLORS, 
                                    reinterpret_cast<void**>(&bitmap_data_), 
                                   NULL, 0);
		SelectObject(hdc_, bitmap_handle_);	
	}
	
        // Doesn't work
	implementation(const std::shared_ptr<frame>& frame)
	: size_(frame->size()), width_(frame->width()), height_(frame->height()), 
           hdc_(CreateCompatibleDC(nullptr)), bitmap_handle_(nullptr), 
             frame_(frame)
	{
		if(hdc_ == nullptr)
			throw std::bad_alloc();

		bitmap_data_ = frame_->data();
		bmp_.bmBits = bitmap_data_;
		bmp_.bmHeight = frame->height();
		bmp_.bmWidth = frame->width();
		bmp_.bmWidthBytes = frame->width()*4;
		bmp_.bmBitsPixel = 32;
		bmp_.bmPlanes = 1;
		bmp_.bmType = 0;
		bitmap_handle_ = CreateBitmapIndirect(&bmp_);
		SelectObject(hdc_, bitmap_handle_);	
	}

	~implementation()
	{
		if(bitmap_handle_ != nullptr) 
			DeleteObject(bitmap_handle_);
		if(hdc_ != nullptr)
			DeleteDC(hdc_);
	}
	
	const size_t size_;
	const size_t width_;
	const size_t height_;
	unsigned char* bitmap_data_;
	HDC hdc_;
	HBITMAP bitmap_handle_;

	BITMAP bmp_;
	std::shared_ptr<frame> frame_;
};
bitmap_frame::bitmap_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}
bitmap_frame::bitmap_frame(const std::shared_ptr<frame>& frame) : impl_(new implementation(frame)){}
size_t bitmap_frame::size() const { return impl_->size_; }
size_t bitmap_frame::width() const { return impl_->width_; }
size_t bitmap_frame::height() const { return impl_->height_; }
unsigned char* bitmap_frame::data() { return impl_->bitmap_data_; }
HDC bitmap_frame::hdc() { return impl_->hdc_; }

I think CreateBitmapIndirect creates a device dependent context, which is why it doesnt work, CreateDIBSection create a device independent context.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.