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);
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
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...
>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.
>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);
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;
}