shinyblog

Wednesday, June 01, 2005

Laszlo!

It's been at least a day since I wrote about how excited I am to be working with Laszlo. Oliver Steele posted a job description which may or may not be the job that I'm filling, but it's close, especially in values and mood. Scott Evans also posted about working at Laszlo. These are cool people, is my point.

I'm going to be in San Francisco/San Mateo from Sunday to Saturday of next week.

Bill Clinton says he weighs just about as much as he did when he graduated from high school.

C++ OpenGL rendering to .NET control

Dana and I worked through some OpenGL setup stuff, and we got C++ OpenGL calls rendering to my .NET control. I get the HDC in C# from the PaintEventArgs, and pass the HDC through to my C++ OpenGL rendering code... and it draws! Mostly.

With my current code, I only see the opengl-painted stuff when I minimize, then maximize the window; my opengl code gets called every paint event, but it only gets drawn visibly after a maximize event. I'm not yet very worried about this, because I'm making a new wglContext every paint event, which is not ideal. My next step is to make one wglContext for a ManagedWindow, and reuse it for subsequent redraws.

Here's the most important nugget of the code

// C#
// Paint handler for my .NET control
private void LeoControl_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
System.IntPtr hdc = e.Graphics.GetHdc();
// Call the C++ internals to render some stuff onto this widget.
CSCppWrapper wrapper = new CSCppWrapper();
// initHDC also draws some test stuff into the HDC
wrapper.initHDC(hdc);
e.Graphics.ReleaseHdc(hdc);
}

// C++
void
CppInternals::initHDC(HDC hdc)
{
_hdc = hdc;

// create and enable the render context (RC)
_hrc = wglCreateContext( _hdc );

PIXELFORMATDESCRIPTOR pfd;
int format;

// set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( _hdc, &pfd );
SetPixelFormat( _hdc, format, &pfd );

renderScene();


// pair with create context call.
wglDeleteContext( _hrc);

}

void
CppInternals::renderScene() {

// Tell it to render to the context we initialized in initHDC
wglMakeCurrent( _hdc, _hrc );

.
.
.
// make some opengl calls here to draw stuff
// ....
.
.
.

// Actually put this opengl stuff on the screen!
// Except, this doesn't seem to actually put the stuff on the screen... I don't think.
SwapBuffers(_hdc);

// Let go of this context
wglMakeCurrent( NULL, NULL);

}


This makes me so very very happy.