// // pbuffer.cxx - pbuffer sample. // Takehiko Terada (terada@siliconstudio.co.jp) // 1999/07/08 // #include #include #include #include #include #include char *className = "OpenGL"; char *windowName = "Simple OpenGL"; int winX = 0, winY = 0; int winWidth = 300, winHeight = 300; float angle = 0.0f; GLubyte *img; HDC hDC, hPBDC; HGLRC hGLRC; HPALETTE hPalette; HPBUFFEREXT hPB; // pixel_format function pointers PFNWGLCHOOSEPIXELFORMATEXTPROC wglChoosePixelFormatEXT; // pbuffer function pointers PFNWGLCREATEPBUFFEREXTPROC wglCreatePbufferEXT; PFNWGLDESTROYPBUFFEREXTPROC wglDestroyPbufferEXT; PFNWGLGETPBUFFERDCEXTPROC wglGetPbufferDCEXT; PFNWGLRELEASEPBUFFERDCEXTPROC wglReleasePbufferDCEXT; PFNWGLQUERYPBUFFEREXTPROC wglQueryPbufferEXT; // make_current_read function pointers PFNWGLMAKECONTEXTCURRENTEXTPROC wglMakeContextCurrentEXT; BOOL CheckForWGLExtension(char *extension) { PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT; const char *p; int n = strlen(extension); wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress("wglGetExtensionsStringEXT"); if (wglGetExtensionsStringEXT == NULL) { return FALSE; } p = wglGetExtensionsStringEXT(); // search for extension name while (p = strstr(p, extension)) { // must be terminated by or if (*(p+n) == ' ' || *(p+n) == '\0') { return GL_TRUE; } // try to find another match ++p; } return GL_FALSE; } int CreatePBuffer(unsigned int pb_width, unsigned int pb_height) { int attr[256]; UINT n; int pixelFormat; int query_val; // get the wgl extension function pointers wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC) wglGetProcAddress("wglChoosePixelFormatEXT"); wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC) wglGetProcAddress("wglCreatePbufferEXT"); wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC) wglGetProcAddress("wglDestroyPbufferEXT"); wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC) wglGetProcAddress("wglGetPbufferDCEXT"); wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC) wglGetProcAddress("wglReleasePbufferDCEXT"); wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC) wglGetProcAddress("wglQueryPbufferEXT"); wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC) wglGetProcAddress("wglMakeContextCurrentEXT"); // choose pixel format n = 0; attr[n++] = WGL_SUPPORT_OPENGL_EXT; attr[n++] = TRUE; attr[n++] = WGL_DRAW_TO_PBUFFER_EXT; attr[n++] = TRUE; attr[n++] = WGL_RED_BITS_EXT; attr[n++] = 8; attr[n++] = WGL_GREEN_BITS_EXT; attr[n++] = 8; attr[n++] = WGL_BLUE_BITS_EXT; attr[n++] = 8; attr[n++] = WGL_DEPTH_BITS_EXT; attr[n++] = 24; attr[n++] = 0; n = 0; wglChoosePixelFormatEXT(hDC, (const int *)attr, NULL, 1, &pixelFormat, &n); if (n == 0) { printf("Error unable to find pbuffer pixel format\n"); return -1; } // create pbuffer device context hPB = wglCreatePbufferEXT(hDC, pixelFormat, pb_width, pb_height, NULL); hPBDC = wglGetPbufferDCEXT(hPB); if(hPBDC == 0){ printf("Error creating pbuffer\n"); // delete the context return -1; } wglQueryPbufferEXT(hPB, WGL_PBUFFER_WIDTH_EXT, &query_val); if(pb_width != query_val){ printf("Width != QueryPbuffer Width\n"); return -1; } wglQueryPbufferEXT(hPB, WGL_PBUFFER_HEIGHT_EXT, &query_val); if(pb_height != query_val){ printf("Height != QueryPbuffer Height\n"); return -1; } return 0; } void init(void) { glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); } void redraw(void) { wglMakeContextCurrentEXT(hPBDC, hPBDC, hGLRC); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)winWidth / (GLfloat)winHeight, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); /* clear color and depth buffers */ glEnable(GL_DEPTH_TEST); glReadBuffer(GL_FRONT); glDrawBuffer(GL_FRONT); glClearColor(0.5f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(angle, 0.0f, 1.0f, 0.0f); /* draw six faces of a cube */ glBegin(GL_QUADS); glNormal3f( 0.0F, 0.0F, 1.0F); glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); glNormal3f( 0.0F, 0.0F,-1.0F); glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); glNormal3f( 0.0F, 1.0F, 0.0F); glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); glNormal3f( 0.0F,-1.0F, 0.0F); glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); glNormal3f( 1.0F, 0.0F, 0.0F); glVertex3f( 0.5F, 0.5F, 0.5F); glVertex3f( 0.5F,-0.5F, 0.5F); glVertex3f( 0.5F,-0.5F,-0.5F); glVertex3f( 0.5F, 0.5F,-0.5F); glNormal3f(-1.0F, 0.0F, 0.0F); glVertex3f(-0.5F,-0.5F,-0.5F); glVertex3f(-0.5F,-0.5F, 0.5F); glVertex3f(-0.5F, 0.5F, 0.5F); glVertex3f(-0.5F, 0.5F,-0.5F); glEnd(); glPopMatrix(); //glReadPixels(0, 0, winWidth, winHeight, GL_RGBA, GL_UNSIGNED_BYTE, // img); wglMakeContextCurrentEXT(hDC, hPBDC, hGLRC); //wglMakeContextCurrentEXT(hDC, hDC, hGLRC); glReadBuffer(GL_FRONT); glDrawBuffer(GL_BACK); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRasterPos2i(-1, -1); glEnable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f, 0.2f, 1.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCopyPixels(0, 0, winWidth, winHeight, GL_COLOR); //glDrawPixels(winWidth, winHeight, GL_RGBA, GL_UNSIGNED_BYTE, img); glFlush(); SwapBuffers(hDC); } void resize(void) { /* set viewport to cover the window */ glViewport(0, 0, winWidth, winHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)winWidth / (GLfloat)winHeight, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); } void setupPixelFormat(HDC hDC) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size */ 1, /* version */ PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER, /* support double-buffering */ PFD_TYPE_RGBA, /* color type */ 24, /* prefered color depth */ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ 0, /* no alpha buffer */ 0, /* alpha bits (ignored) */ 0, /* no accumulation buffer */ 0, 0, 0, 0, /* accum bits (ignored) */ 24, /* depth buffer */ 0, /* no stencil buffer */ 0, /* no auxiliary buffers */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0, /* no layer, visible, damage masks */ }; int pixelFormat; pixelFormat = ChoosePixelFormat(hDC, &pfd); if (pixelFormat == 0) { MessageBox(WindowFromDC(hDC), "ChoosePixelFormat failed.", "Error", MB_ICONERROR | MB_OK); exit(1); } if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) { MessageBox(WindowFromDC(hDC), "SetPixelFormat failed.", "Error", MB_ICONERROR | MB_OK); exit(1); } } void setupPalette(HDC hDC) { int pixelFormat = GetPixelFormat(hDC); PIXELFORMATDESCRIPTOR pfd; LOGPALETTE* pPal; int paletteSize; DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); if (pfd.dwFlags & PFD_NEED_PALETTE) { paletteSize = 1 << pfd.cColorBits; } else { return; } pPal = (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = paletteSize; /* build a simple RGB color palette */ { int redMask = (1 << pfd.cRedBits) - 1; int greenMask = (1 << pfd.cGreenBits) - 1; int blueMask = (1 << pfd.cBlueBits) - 1; int i; for (i=0; ipalPalEntry[i].peRed = (((i >> pfd.cRedShift) & redMask) * 255) / redMask; pPal->palPalEntry[i].peGreen = (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; pPal->palPalEntry[i].peBlue = (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; pPal->palPalEntry[i].peFlags = 0; } } hPalette = CreatePalette(pPal); free(pPal); if (hPalette) { SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); } } void myQuit(void) { wglReleasePbufferDCEXT(hPB, hPBDC); wglDestroyPbufferEXT(hPB); } LRESULT APIENTRY WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: /* initialize OpenGL rendering */ hDC = GetDC(hWnd); setupPixelFormat(hDC); setupPalette(hDC); hGLRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hGLRC); resize(); init(); if (CreatePBuffer(winWidth, winHeight)) { MessageBox(NULL, "Error in CreatePBuffer", "Error", MB_OK); myQuit(); exit(-1); } wglMakeContextCurrentEXT(hPBDC, hPBDC, hGLRC); resize(); init(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); wglMakeContextCurrentEXT(hDC, hDC, hGLRC); img = (GLubyte *)malloc(winWidth * winHeight * 4); memset(img, 0xff, winWidth * winHeight * 4); return 0; case WM_DESTROY: /* finish OpenGL rendering */ if (hGLRC) { myQuit(); wglMakeCurrent(NULL, NULL); wglDeleteContext(hGLRC); } if (hPalette) { DeleteObject(hPalette); } ReleaseDC(hWnd, hDC); PostQuitMessage(0); return 0; case WM_SIZE: /* track window size changes */ if (hGLRC) { winWidth = (int) LOWORD(lParam); winHeight = (int) HIWORD(lParam); resize(); return 0; } case WM_PALETTECHANGED: /* realize palette if this is *not* the current window */ if (hGLRC && hPalette && (HWND) wParam != hWnd) { UnrealizeObject(hPalette); SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); redraw(); break; } break; case WM_QUERYNEWPALETTE: /* realize palette if this is the current window */ if (hGLRC && hPalette) { UnrealizeObject(hPalette); SelectPalette(hDC, hPalette, FALSE); RealizePalette(hDC); redraw(); return TRUE; } break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); if (hGLRC) { redraw(); } EndPaint(hWnd, &ps); return 0; } break; case WM_CHAR: /* handle keyboard input */ switch ((int)wParam) { case VK_ESCAPE: DestroyWindow(hWnd); return 0; default: break; } break; default: break; } return DefWindowProc(hWnd, message, wParam, lParam); } void myIdle(HDC hdc) { redraw(); angle += 1.0f; } int APIENTRY WinMain( HINSTANCE hCurrentInst, HINSTANCE hPreviousInst, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wndClass; HWND hWnd; MSG msg; /* register window class */ wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hCurrentInst; wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = className; RegisterClass(&wndClass); /* create window */ hWnd = CreateWindow( className, windowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, winX, winY, winWidth, winHeight, NULL, NULL, hCurrentInst, NULL); /* display window */ ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); /* process messages */ while(1) { while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == FALSE) { myIdle(hDC); } if (GetMessage(&msg, NULL, 0, 0) != TRUE) break; TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }