Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DC and RC for offscreen rendering

594 views
Skip to first unread message

Luca Vacchetti

unread,
Jul 6, 2001, 10:05:29 AM7/6/01
to
Hello,

I am trying to follow the suggestion I received on this newsgroup about
offscreen rendering using wgl extensions. By the way, thanks for the
advices!
Now I have trouble with Windows SDK commands. While it's very easy to take a
device context from the current window, I don't know how to create a brand
new one from the scratch, and then use it as a buffer for my offscreen
rendering. What I did is the following , but it seems to work up to the
ChoosePixelformat, and then it gives errors....
Help!!


Luca

////////////////////////////////////////////////////////////

PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_BITMAP | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
//PFD_GENERIC_ACCELERATED | /////HW acceleration
PFD_SUPPORT_GDI, //////////
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};

hdc = CreateCompatibleDC(0); ////seems to work, it gives back a hdc

HBITMAP bitmap = CreateCompatibleBitmap(hdc,768,576);/////seems also to work
//HBITMAP bitmap =
CreateDIBSection(hdc,pBitmapInfo,DIB_RGB_COLORS,(void**)RendImg,NULL,NULL);/
///this doesn't work

int PixelFormat = ChoosePixelFormat(hdc,&pfd);////seems ok

int b = SetPixelFormat(hdc, PixelFormat, &pfd); /////b will be 0 :-( it
means it fails :-( after this everything is wrong

// create a rendering context
hglrc = wglCreateContext (hdc);

// make it the calling thread's current rendering context
int a = wglMakeCurrent (hdc, hglrc);


Jakob Bieling

unread,
Jul 6, 2001, 12:03:12 PM7/6/01
to
> hdc = CreateCompatibleDC(0); ////seems to work, it gives back a hdc
>
> HBITMAP bitmap = CreateCompatibleBitmap(hdc,768,576);/////seems also to
work

change both lines to:

/* get DC of whole desktop */
HDC hdcDesktop = GetDC (0);
hdc = CreateCompatibleDC (hdcDesktop);

/* create a bitmap that is compatible with the bitmap of the hdcDesktop. if
you use the newly created hdc to create a compatible bitmap, this bitmap
will be black-white only. */
HBITMAP hbitmap = CreateCompatibleBitmap(hdcDekstop,768,576);

/* now select the bitmap into our hdc */
SelectObject (hdc, hbitmap);

/* release the desktop hdc, since we don't need it anymore */
ReleaseDC (hdcDekstop);

not sure about the dib-section stuff, since i use them rarely if at all :)

regards,
jb


Jason Allen

unread,
Jul 6, 2001, 10:13:26 PM7/6/01
to
Why don't you look into using pixel buffers (WGL_ARB_pbuffer and
WGL_ARB_pixel_format) for offscreen rendering? I have a pbuffer class (for
Delphi and C++) on my website that allows you to do the following to create
an offscreen buffer:

CPixelBuffer pbuf;
InitPBuffers(); // check for extensions
pbuf.Init(256, 256, 16, 0, true); // create 256x256 16bit buffer
pbuf.Activate();
//render whatever you want
pbuf.Deactivate();

//render to main window

Thats all you have to do.

Jason A.
DelphiGL (http://delphigl.cfxweb.net)
"Luca Vacchetti" <vacc...@lig.di.epfl.ch> wrote in message
news:3b45c6ca$1...@epflnews.epfl.ch...

Matt Feinstein

unread,
Jul 9, 2001, 8:51:43 AM7/9/01
to
On Fri, 6 Jul 2001 16:05:29 +0200, "Luca Vacchetti"
<vacc...@lig.di.epfl.ch> wrote:

>Hello,
>
>I am trying to follow the suggestion I received on this newsgroup about
>offscreen rendering using wgl extensions. By the way, thanks for the
>advices!
>Now I have trouble with Windows SDK commands. While it's very easy to take a
>device context from the current window, I don't know how to create a brand
>new one from the scratch, and then use it as a buffer for my offscreen
>rendering. What I did is the following , but it seems to work up to the
>ChoosePixelformat, and then it gives errors....
>Help!!
>
>

For what it's worth, here's the code that I've been using lately; it's
taken, more or less as is, from the OpenGL Superbible. It seems to
work. Note: I am generally ignorant about Win32 stuff. Your mileage
may vary.

/* BEGIN Windows API hocus-pocus */

dc = CreateCompatibleDC(NULL);

memset(&info, 0, sizeof(info));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = Output.PixH;
info.bmiHeader.biHeight = Output.PixV;
info.bmiHeader.biPlanes = 1;
if (Output.PixFormat == RGB24)
{
info.bmiHeader.biBitCount = 8*3;
info.bmiHeader.biCompression = BI_RGB;
}

if (Output.PixFormat == RGB24)
bitmap = CreateDIBSection(dc, &info, DIB_RGB_COLORS,
&outbits, NULL, 0);
SelectObject(dc, bitmap);

memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
if (Output.PixFormat == RGB24)
{
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 8*3;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
}
pfd.cDepthBits = 32;

pf = ChoosePixelFormat(dc, &pfd);
SetPixelFormat(dc, pf, &pfd);
rc = wglCreateContext(dc);
wglMakeCurrent(dc, rc);
/* END Windows API hocus-pocus */

Matt Feinstein matt.fe...@jhuapl.edu
--------
Harvard Law of Automotive Repair: Anything that goes away
by itself will come back by itself.

Matt Feinstein

unread,
Jul 9, 2001, 8:55:59 AM7/9/01
to
On Fri, 6 Jul 2001 16:05:29 +0200, "Luca Vacchetti"
<vacc...@lig.di.epfl.ch> wrote:

>Hello,
>
>I am trying to follow the suggestion I received on this newsgroup about
>offscreen rendering using wgl extensions. By the way, thanks for the
>advices!
>Now I have trouble with Windows SDK commands. While it's very easy to take a
>device context from the current window, I don't know how to create a brand
>new one from the scratch, and then use it as a buffer for my offscreen
>rendering. What I did is the following , but it seems to work up to the
>ChoosePixelformat, and then it gives errors....
>Help!!
>

Left a couple of things out:
-- -these are the variable declarations:

HDC dc;
HBITMAP bitmap;
BITMAPINFO info;
PIXELFORMATDESCRIPTOR pfd;
int pf;
HGLRC rc;

--- and this is the clean-up:

wglDeleteContext(rc);
DeleteObject(bitmap);
DeleteDC(dc);

Luca Vacchetti

unread,
Jul 16, 2001, 5:07:36 PM7/16/01
to
I realized this procedure to "enable" the offscreen rendering using Win32
memory DCs.
It doesn't work.

The structure of my program is

-OffScreenInit; to set up a memory DC, so that next Opengl commands will
render on it
-Some Opengl (that works on the screen, if you just take away the call to
OffScreenInit)
-SaveBmp: to save your memory bmp to a file (I put this procedure here just
to be complete, it has been working with another application).

What is wrong in my DC and RC declaration/binding ????
Hope someone konws.............

Luca

P.S. Is there a faster method to do offscreen rendering using Win32? Should
I try to use the back buffer and then using a copypixel, getpixel or
whatever??


/***************************************************************************
******
FUNCTION : OffScreenInit

INPUT : -
OUTPUT : -

REMQ : Initializes the offscreen rendering, after this procedure's call
every OpenGL command will
be forwarded to a memory bitmap.
****************************************************************************
*****/

Energy::OffScreenInit()
{
dc = CreateCompatibleDC(NULL);///////creates a Device context

//int ScreenWidth = GetDeviceCaps(dc, HORZRES);
//int ScreenHeight = GetDeviceCaps(dc, VERTRES);

memset(&info, 0, sizeof(info));

info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = 768;
info.bmiHeader.biHeight = 576;
info.bmiHeader.biPlanes = 1;


info.bmiHeader.biBitCount = 8*3;
info.bmiHeader.biCompression = BI_RGB;

bitmap = CreateDIBSection(dc, &info, DIB_RGB_COLORS,(void **)&outbits, NULL,
0);//////creates a Device Independent Bitmap for the rendering

if (bitmap == NULL)
{
(void) MessageBox(WindowFromDC(dc),"Failed to create DIBSection.","OpenGL
application error",MB_ICONERROR | MB_OK);
exit(1);
}

//MyGetErrors("createdibsection");

HGDIOBJ res = SelectObject(dc, bitmap);///////associates the Bitmap to our
device context

memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;

pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI ;


pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 8*3;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cDepthBits = 32;

pf = ChoosePixelFormat(dc, &pfd);

int result = SetPixelFormat(dc, pf, &pfd);

rc = wglCreateContext(dc);//////////////////creation of an OpenGL rendering
context inside the device context

int resu = wglMakeCurrent(dc, rc);

}


/***************************************************************************
******
FUNCTION : SaveBmp

INPUT : - The name of the file you want to write to.
OUTPUT : -

REMQ : Saves the rendered screen (if you do an offscreen rendering)
****************************************************************************
*****/
Energy::SaveBmp(char *filename)
{

BITMAPFILEHEADER bmFileHeader;
bmFileHeader.bfType = 19778;
bmFileHeader.bfSize = (768 * 576 * 3) + 40 + 14;
bmFileHeader.bfReserved1 = 0;
bmFileHeader.bfReserved2 = 0;
bmFileHeader.bfOffBits = 54;

unsigned char * data = new unsigned char[768*576 * 3];
void * lpvpxldata = (void *)data;

GetDIBits(dc, bitmap, 0, 576, lpvpxldata, &info, DIB_RGB_COLORS);

int bmfile = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
S_IWRITE);
write(bmfile, &bmFileHeader, 14);
write(bmfile, &info, 40);
write(bmfile, lpvpxldata, 768 * 576 * 3);

// clean up
close(bmfile);
free(lpvpxldata);

cout << " saved 1 bitmap as: " << filename << "\n" << endl;

}

0 new messages