PDA

View Full Version : IViewObjectEx->Draw to PBO



ronag
09-25-2010, 04:17 PM
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?

mfort
09-26-2010, 01:14 AM
It should be possible. Create HBITMAP by CreateBitmapIndirect() with PBO data.

ronag
09-26-2010, 01:25 AM
It should be possible. Create HBITMAP by CreateBitmapIndirect() with PBO data.

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

mfort
09-26-2010, 01:46 AM
create PBO, map it to get memory pointer, create BITMAP structure (set bmBits to PBO memory) and call CreateBitmapIndirect to get HBITMAP.

ronag
09-26-2010, 01:47 AM
I also found these function:

wglGetPbufferDCARB()
wglCreateContext()

Still looking into them.

ronag
09-26-2010, 02:21 AM
create PBO, map it to get memory pointer, create BITMAP structure (set bmBits to PBO memory) and call CreateBitmapIndirect to get HBITMAP.

Could work. Will try it during next week.

ronag
09-26-2010, 04:50 AM
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**>(&amp;bitmap_data_),
NULL, 0);
SelectObject(hdc_, bitmap_handle_);
}

// Doesn't work
implementation(const std::shared_ptr<frame>&amp; 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(&amp;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>&amp; 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_; }

ronag
09-28-2010, 12:05 PM
I think CreateBitmapIndirect creates a device dependent context, which is why it doesnt work, CreateDIBSection create a device independent context.