Layertechnik bei OpenGL
-
Hi,
ich programmiere zur Zeit unter C++ in OpenGl ein 2D-Diagramm zur Darstellung von Realtimewerten(nur Darstellung kein Speichern der Werte). Bin sowohl in C++ als auch OpenGl noch Anfänger. Mit Hilfe von Tutorials und Forumbeiträgen habe ich es auch geschafft dieses ordnungsgemäß darzustellen. Nun möchte ich jedoch während der Laufzeit die Skalierung des Diagramms ändern. Dazu möchte ich gerne Achsen und die Wertekurve auf verschiedene Layer legen(bisher gibt es nur den Main) und dann die Wertekurve bei Änderungen stauchen oder strecken. Leider schaffe ich es nicht diese Layersache zu programmieren, bei mir wird immer nur der Main-Layer angezeigt, die anderen werden jedoch nicht beachtet.
Habe schon überall gesucht um ein Beispielprogramm, Tutorial etc. zu finden und auch schon die entsprechenden MSDN-Befehle wie wglDescribeLayerPlane etc. bemüht, aber außer dem MainLayer wird nichts angezeigt.
Ich wäre nun für ein Tutorial, ein Beispielprogramm oder Quelltext sehr dankbar. Ich glaube irgendwas paßt bei meinen PIXELFORMATDESCRIPTOR oder LAYERPLANEDESCRIPTOR nicht.PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER | // double buffered PFD_SWAP_LAYER_BUFFERS, // enables swaplayerbuffers 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 0, // main layer, ignored 0x03, // reserved 0, RGB(1.0,1.0,1.0), 0 // layer masks ignored }; LAYERPLANEDESCRIPTOR plpd = { sizeof(LAYERPLANEDESCRIPTOR), 1, LPD_SUPPORT_OPENGL | LPD_DOUBLEBUFFER | LPD_TRANSPARENT | LPD_SHARE_DEPTH | LPD_SHARE_STENCIL | LPD_SHARE_ACCUM, LPD_TYPE_RGBA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, RGB(1.0, 1.0, 1.0) };
Aufruf in der Funktion zur Initialisierung der Layer
wglDescribeLayerPlane( hdc, // device context whose layer planes are of //interest 0, // pixel format of the desired layer plane 1, // specifies an overlay or underlay plane sizeof(LAYERPLANEDESCRIPTOR), // specifies the size, in bytes, of a // LAYERPLANEDESCRIPTOR structure &plpd // points to a LAYERPLANEDESCRIPTOR structure ); hglrc_text = wglCreateLayerContext(hdc, 1);
-
Habe nun doch eine Beispielprogramm gefunden. Leider sagt es nach dem Ausführen, dass meine Hardware keine Overlayplanes unterstützt. Da ich das nun aber auf mehreren verschiedenen Rechnern immer mit dem selben Ergebnis ausgeführt habe kann ich den Einstellungen auch nicht trauen, oder ist es wirklich so, dass nur sehr wenige Grafikkarten dieses Overlay unterstützen?
hier der Code, den ich gefunden habe, vielleicht findet ja jemand einen Fehler.
/* * overlay.c * * WGL/OpenGL program * * Copyright (C) 1997 by Nate Robins (ndr@pobox.com) * * This program is freely distributable without licensing fees and is * provided without guarantee or warrantee expressed or implied. This * program is not in the public domain. */ /* includes */ #include <windows.h> /* must include this before GL/gl.h */ #include <GL/gl.h> /* OpenGL header file */ #include <stdio.h> /* pragmas */ #pragma warning(disable : 4244) /* disable conversion warnings */ /* globals */ HDC hDC; /* device context */ HGLRC hRC; /* opengl context */ HGLRC hOverlayRC; /* opengl overlay context */ /* functions */ /* WindowProc() * Minimum Window Procedure */ LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LONG lRet = 1; PAINTSTRUCT ps; switch(uMsg) { case WM_CREATE: break; case WM_DESTROY: break; case WM_PAINT: BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_CHAR: if(wParam == 27) /* ESC */ PostQuitMessage(0); break; case WM_SIZE: wglMakeCurrent(hDC, hRC); glViewport(0, 0, LOWORD(lParam), HIWORD(lParam)); wglMakeCurrent(hDC, hOverlayRC); glViewport(0, 0, LOWORD(lParam), HIWORD(lParam)); break; case WM_CLOSE: PostQuitMessage(0); break; default: lRet = DefWindowProc(hWnd, uMsg, wParam, lParam); break; } return lRet; } /* oglCreateWindow * Create a window suitable for OpenGL rendering */ HWND oglCreateWindow(char* title, int x, int y, int width, int height) { WNDCLASS wc; HWND hWnd; HINSTANCE hInstance; /* get this modules instance */ hInstance = GetModuleHandle(NULL); /* fill in the window class structure */ wc.style = 0; /* no special styles */ wc.lpfnWndProc = (WNDPROC)WindowProc; /* event handler */ wc.cbClsExtra = 0; /* no extra class data */ wc.cbWndExtra = 0; /* no extra window data */ wc.hInstance = hInstance; /* instance */ wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); /* load a default icon */ wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */ wc.hbrBackground = NULL; /* redraw our own bg */ wc.lpszMenuName = NULL; /* no menu */ wc.lpszClassName = title; /* use a special class */ /* register the window class */ if (!RegisterClass(&wc)) { MessageBox(NULL, "RegisterClass() failed: Cannot register window class,", "Error", MB_OK); return NULL; } /* create a window */ hWnd = CreateWindow(title, /* class */ title, /* title (caption) */ WS_OVERLAPPEDWINDOW | /* resize handles, etc */ WS_CLIPSIBLINGS | WS_CLIPCHILDREN, /* style */ x, y, width, height, /* dimensions */ NULL, /* no parent */ NULL, /* no menu */ hInstance, /* instance */ NULL); /* don't pass anything to WM_CREATE */ /* make sure we got a window */ if (hWnd == NULL) { MessageBox(NULL, "CreateWindow() failed: Cannot create a window.", "Error", MB_OK); return NULL; } /* show the window (map it) */ ShowWindow(hWnd, SW_SHOW); /* send an initial WM_PAINT message (expose) */ UpdateWindow(hWnd); return hWnd; } /* oglPixelFormat() * Sets the pixel format for the context */ int oglSetPixelFormatOverlay(HDC hDC, BYTE type, DWORD flags) { int pf, maxpf; PIXELFORMATDESCRIPTOR pfd; LAYERPLANEDESCRIPTOR lpd; /* layer plane descriptor */ int nEntries = 2; /* number of entries in palette */ COLORREF crEntries[2] = { /* entries in custom palette */ 0x00000000, /* black (ref #0 = transparent) */ 0x00ff0000, /* blue */ }; /* get the maximum number of pixel formats */ maxpf = DescribePixelFormat(hDC, 0, 0, NULL); /* find an overlay layer descriptor */ for(pf = 0; pf < maxpf; pf++) { DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* the bReserved field of the PIXELFORMATDESCRIPTOR contains the number of overlay/underlay planes */ if (pfd.bReserved > 0) { /* aha! This format has overlays/underlays */ wglDescribeLayerPlane(hDC, pf, 1, sizeof(LAYERPLANEDESCRIPTOR), &lpd); if (lpd.dwFlags & LPD_SUPPORT_OPENGL && lpd.dwFlags & flags) { goto found; } } } /* couldn't find any overlay/underlay planes */ MessageBox(NULL, "Fatal Error: Hardware does not support overlay planes.", "Error", MB_OK); return 0; found: /* now get the "normal" pixel format descriptor for the layer */ DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* set the pixel format */ if(SetPixelFormat(hDC, pf, &pfd) == FALSE) { MessageBox(NULL, "SetPixelFormat() failed: Cannot set format specified.", "Error", MB_OK); return 0; } /* set up the layer palette */ wglSetLayerPaletteEntries(hDC, 1, 0, nEntries, crEntries); /* realize the palette */ wglRealizeLayerPalette(hDC, 1, TRUE); /* announce what we've got */ printf("Number of overlays = %d\n", pfd.bReserved); printf("Color bits in the overlay = %d\n", lpd.cColorBits); return pf; } /* main() * Entry point */ int main(int argc, char** argv) { HWND hWnd; /* window */ MSG msg; /* message */ /* create a window */ hWnd = oglCreateWindow("OpenGL", 0, 0, 200, 200); if (hWnd == NULL) exit(1); /* get the device context */ hDC = GetDC(hWnd); /* set the pixel format */ if (oglSetPixelFormatOverlay(hDC, PFD_TYPE_RGBA, LPD_DOUBLEBUFFER) == 0) exit(1); /* get the device context */ hDC = GetDC(hWnd); /* create an OpenGL overlay context */ hOverlayRC = wglCreateLayerContext(hDC, 1); /* create an OpenGL context */ hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); /* now we can start changing state & rendering */ while(1) { /* first, check for (and process) messages in the queue */ while(PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE)) { if(GetMessage(&msg, hWnd, 0, 0)) { TranslateMessage(&msg); /* translate virtual-key messages */ DispatchMessage(&msg); /* call the window proc */ } else { goto quit; } } /* make current and draw a triangle */ wglMakeCurrent(hDC, hRC); glClear(GL_COLOR_BUFFER_BIT); glRotatef(1.0, 0.0, 0.0, 1.0); glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2i( 0, 1); glColor3f(0.0, 1.0, 0.0); glVertex2i(-1, -1); glColor3f(0.0, 0.0, 1.0); glVertex2i( 1, -1); glEnd(); glFlush(); wglSwapLayerBuffers(hDC, WGL_SWAP_MAIN_PLANE); /* make current and draw a triangle */ wglMakeCurrent(hDC, hOverlayRC); glClear(GL_COLOR_BUFFER_BIT); glRotatef(-1.0, 0.0, 0.0, 1.0); glBegin(GL_TRIANGLES); glIndexi(1); glVertex2i( 0, 1); glVertex2i(-1, -1); glVertex2i( 1, -1); glEnd(); glFlush(); wglSwapLayerBuffers(hDC, WGL_SWAP_OVERLAY1); } quit: /* clean up */ wglMakeCurrent(NULL, NULL); /* make our context 'un-'current */ ReleaseDC(hDC, hWnd); /* release handle to DC */ wglDeleteContext(hRC); /* delete the rendering context */ wglDeleteContext(hOverlayRC); /* delete the overlay context */ DestroyWindow(hWnd); /* destroy the window */ return TRUE; }