PDA

View Full Version : Render to DIB



lhaave
02-19-2004, 02:56 AM
I'm having difficulties rendering to my DIB.
When i'm rendering to a window, it looks fine, but when i use the same render function to render on the DIB, it looks like the Depth info is lost. Light source is also missing.
Has anyone managed to render directly to a DIB ?

Relic
02-19-2004, 03:53 AM
Rendering to a Windows bitmap directly is only supported by the Windows GDI Generic OpenGL implementation rendering in SW.
If your image is different you may have lost all special features of a hardware implementaion you might use in your windowed rendering, or you did something wrong, or found a bug in one of the implementations used.

Check this: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnopen/html/msdn_gl6.asp

[This message has been edited by Relic (edited 02-19-2004).]

lhaave
02-19-2004, 05:32 AM
Well, here is my code for creating a dib and do some rendering to it:


This is my Init:
void SetupRC()
{
// Light values and coordinates
GLfloat whiteLight[] = { 0.45f, 0.45f, 0.45f, 1.0f };
GLfloat sourceLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
GLfloat lightPos[] = { -50.f, 25.0f, 250.0f, 0.0f };

glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);

// Enable lighting
glEnable(GL_LIGHTING);

// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_AMBIENT,sourceLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);

// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// Black blue background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

//Create DIB
create_offscreen_DIB();
}

void create_offscreen_DIB()
{

dib_dc = CreateCompatibleDC(NULL);

/* Create and bind the bitmap */
memset(&dib_info, 0, sizeof(dib_info));
dib_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dib_info.bmiHeader.biWidth = WINDOW_WIDTH;
dib_info.bmiHeader.biHeight = WINDOW_HEIGHT;
dib_info.bmiHeader.biPlanes = 1;
dib_info.bmiHeader.biBitCount = 32;
dib_info.bmiHeader.biCompression = BI_RGB;

dib_bitmap = CreateDIBSection(dib_dc, &dib_info, DIB_RGB_COLORS, (void**)(&dib_bits), NULL, 0);
SelectObject(dib_dc,dib_bitmap);

/* Set the pixel format... */
memset(&dib_pfd, 0, sizeof(dib_pfd));
dib_pfd.nSize = sizeof(dib_pfd);
dib_pfd.nVersion = 1;
dib_pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI ;
dib_pfd.iPixelType = PFD_TYPE_RGBA;
dib_pfd.cColorBits = (BYTE)dib_info.bmiHeader.biBitCount;
dib_pfd.cRedBits = 8;
dib_pfd.cGreenBits = 8;
dib_pfd.cBlueBits = 8;
dib_pfd.cDepthBits = 8;
dib_pfd.iLayerType = PFD_MAIN_PLANE;
dib_pf = ChoosePixelFormat(dib_dc, &dib_pfd);
SetPixelFormat(dib_dc, dib_pf, &dib_pfd);

dib_rc = wglCreateContext(dib_dc);
wglMakeCurrent(dib_dc, dib_rc);

}


Then in my onDraw function, i do this:

.
.
.
.
// DIB rendering
wglMakeCurrent(dib_dc, dib_rc);
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, fAspect, 1, 400.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
RenderScene();
StretchBlt(hDC,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,dib_ dc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,SRCCOPY); //this is just for viewing my DIB render result in a window.
glFlush();
.
.
.
.
.

Could someone comment this way to create a DIB if it is wrong !?!

lhaave
02-21-2004, 09:03 AM
After some investigation, i think the solution to my problem would be to render to a p-buffer. But when creating a p-buffer, opengl requires a valid DC. So i should first create a window (hidden), create my p-buffer, and then destroy the window.

Is this something that could work? (i guess the best way to find out is to try it out http://www.opengl.org/discussion_boards/ubb/smile.gif )

jwatte
02-21-2004, 12:20 PM
That's the only way to do it. In fact, you may need to create more than one window, because there's no way of getting the context creation extensions without first having a plain-old context, and you need those extensions to specify that you want to draw to a pbuffer.

Why can't you just render to the back buffer, and then readpixels or copytexsubimage to get the data where you want it? You don't need to display those pixels; you can clear before you render what you actually want to display.

The one reason I know of to use pbuffers is when you can't guarantee you're fullscreen or the frontmost window.