📄 oglwindow.cpp
字号:
"Cannot handle pbuffers greater than 2048"); GPUAssert(numOutputs < 5, "Cannot handle more than 4 outputs"); GPUAssert(numOutputs > 0, "Creating Pbuffer with zero outputs?"); /* Tear down the old pbuffer */ if (!wglMakeCurrent (hpbufferdc, NULL)) GPUError("MakeCurrent Failed"); if (!wglReleasePbufferDCARB (hpbuffer, hpbufferdc)) GPUError("ReleasePbufferDC Failed"); if (!wglDestroyPbufferARB (hpbuffer)) GPUError("DestroyPbufferARB Failed"); GPUAssert(hwindowdc, "hwindowdc = NULL"); GPUAssert(pixelformat[numOutputs-1][numComponents-1], "Invalid pixelformat"); GPUAssert(piAttribList[numComponents-1], "Invalid piAttribList"); GPUAssert(2048, "Bogus 2048"); /* Find the largest power of two which contains the size */ if (width > currentPbufferWidth) { for (i=16; i<width; i*=2) /* do nothing */; GPUAssert(i<=2048, "Cannot create pbuffers larger than 2048"); currentPbufferWidth = i; } if (height > currentPbufferHeight) { for (i=16; i<height; i*=2) /* do nothing */; GPUAssert(i<=2048, "Cannot create pbuffers larger than 2048"); currentPbufferHeight = i; } currentPbufferComponents = numComponents; /* Create a fresh pbuffer */ hpbuffer = wglCreatePbufferARB(hwindowdc, pixelformat [currentPbufferOutputs < numOutputs ? (numOutputs-1) : (currentPbufferOutputs-1)] [numComponents-1], currentPbufferWidth, currentPbufferHeight, piAttribList[numComponents-1]); if (!hpbuffer) GPUError("Failed to create pbuffer, possibly out of memory"); hpbufferdc = wglGetPbufferDCARB (hpbuffer); if (!hpbufferdc) GPUError("Failed to get pbuffer dc"); if (currentPbufferOutputs < numOutputs) { // Since there are a different number of buffers // we have to create a new context HGLRC new_hglrc; new_hglrc = wglCreateContext( hpbufferdc ); GPUAssert(new_hglrc, "Invalid glrc"); if (!wglShareLists(hglrc, new_hglrc)) GPUError("wglShareLists failed"); hglrc = new_hglrc; currentPbufferOutputs = numOutputs; switched_contexts = true; } GPUAssert(hglrc, "Invalid glrc"); if (!wglMakeCurrent( hpbufferdc, hglrc )) GPUError("Failed to make current GL context"); glEnable(GL_FRAGMENT_PROGRAM_ARB); return switched_contexts;}#else/* Linux version */#include <X11/Xlib.h>#include <GL/gl.h>#include <GL/glx.h>/*** Static OGLWindow members:**** For some reason, NVIDIA drivers don't seem to ** like me creating a window, then destroying it, ** then creating a new window and pbuffer.** The driver hangs inside of gl calls.** However if I just create a window and pbuffer** it is fine. So we switched to using a static ** window and pbuffer. Lame but it works.*/Display *OGLWindow::pDisplay;int OGLWindow::iScreen;Window OGLWindow::glxWindow;Colormap OGLWindow::cmap;XVisualInfo *OGLWindow::visual;GLXFBConfig *OGLWindow::glxConfig[4];GLXPbuffer OGLWindow::glxPbuffer;GLXContext OGLWindow::glxContext;int OGLWindow::piAttribList[4][16];bool OGLWindow::static_window_created = false;bool OGLWindow::static_pbuffers_initialized = false;//This is non square because ATI can't do 2048^2 for some odd reason#define PBUFFER_WIDTH 2048#define PBUFFER_HEIGHT 1024#define CRGBA(c, r,g,b,a) \ GLX_RED_SIZE, r, \ GLX_GREEN_SIZE, g, \ GLX_BLUE_SIZE, b, \ GLX_ALPHA_SIZE, a, \ GLX_STENCIL_SIZE, 0, \ GLX_DEPTH_SIZE, 0, \ GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, \ GLX_DOUBLEBUFFER, 0#define BASEIATTRIB { \{CRGBA(32,32,0,0,0), 0, 0}, \{CRGBA(64,32,32,0,0), 0, 0}, \{CRGBA(96,32,32,32,0), 0, 0}, \{CRGBA(128,32,32,32,32), 0, 0} }static const int baseiAttribList[4][4][64] = { BASEIATTRIB, BASEIATTRIB, BASEIATTRIB, BASEIATTRIB};static const floatbasefAttribList[4][16] = { {0.0f,0.0f}, {0.0f,0.0f}, {0.0f,0.0f}, {0.0f,0.0f}};#define PBATTRIB \ GLX_PRESERVED_CONTENTS, GL_TRUE, \ GLX_PBUFFER_WIDTH, PBUFFER_WIDTH, \ GLX_PBUFFER_HEIGHT, PBUFFER_HEIGHT, \ GLX_LARGEST_PBUFFER, 0static intbasepiAttribList[4][16] = { {PBATTRIB, 0, 0}, \ {PBATTRIB, 0, 0}, \ {PBATTRIB, 0, 0}, \ {PBATTRIB, 0, 0}};OGLWindow::OGLWindow() { int attrib[] = { GLX_RGBA, None }; XSetWindowAttributes swa; /* Bail if the window is already created */ if (static_window_created) return; pDisplay = XOpenDisplay(NULL); if (pDisplay == NULL) { fprintf (stderr, "Could not connect to X Server.\n"); exit(1); } iScreen = DefaultScreen(pDisplay); visual = glXChooseVisual(pDisplay, iScreen, attrib); if (visual == NULL) { fprintf (stderr, "Could not create window visual.\n"); exit(1); } glxContext = glXCreateContext(pDisplay, visual, 0, GL_TRUE); if (glxContext == NULL) { fprintf (stderr, "Could not create GL Context.\n"); exit(1); } cmap = XCreateColormap (pDisplay, RootWindow(pDisplay, iScreen), visual->visual, AllocNone); swa.border_pixel = 0; swa.colormap = cmap; glxWindow = XCreateWindow(pDisplay, RootWindow(pDisplay, iScreen), 0, 0, 1, 1, 0, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWColormap, &swa); if (!glXMakeCurrent(pDisplay, glxWindow, glxContext)) { fprintf (stderr, "OGLWindow: Could not make current.\n"); exit(1); } glFinish(); initglfunc(); static_window_created = true;}void OGLWindow::initPbuffer( const int (*viAttribList)[4][64], const float (*vfAttribList)[4][16], const int (*vpiAttribList)[4][16]) { int iConfigCount; int i; /* Bail if the pbuffers are already initialized */ if (static_pbuffers_initialized) return; int (*iAttribList)[4][64] = (int (*)[4][64]) malloc (sizeof(baseiAttribList)); float fAttribList[4][16] = {{0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}}; memcpy(iAttribList, baseiAttribList, sizeof(baseiAttribList)); memcpy(piAttribList, basepiAttribList, sizeof(basepiAttribList)); /* Append vendor specific attribs */ appendVendorAttribs( iAttribList, fAttribList, piAttribList, viAttribList, vfAttribList, vpiAttribList); if (pDisplay == NULL) { fprintf (stderr, "Could not connect to X Server.\n"); exit(1); } // Destroy Window glXMakeCurrent(pDisplay, None, NULL); glXDestroyContext(pDisplay, glxContext); XDestroyWindow(pDisplay, glxWindow); XFreeColormap(pDisplay, cmap); XFree(visual); for (i=0; i<4; i++) { glxConfig[i] = glXChooseFBConfig(pDisplay, iScreen, iAttribList[0][i], &iConfigCount); if (iConfigCount == 0) { fprintf (stderr, "OGL Window: No floating point pbuffer " "format found for float%d.\n", i+1); exit(1); } if (!glxConfig[i] || !glxConfig[i][0]) { fprintf(stderr, "OGL Window: glXChooseFBConfig() failed\n"); exit(1); } } glxPbuffer = glXCreatePbuffer(pDisplay, glxConfig[3][0], piAttribList[3]); if (!glxPbuffer) { fprintf(stderr, "OGL Window: glXCreatePbuffer() failed\n"); exit(1); } // Default to the 4 component glxContext = glXCreateNewContext(pDisplay, glxConfig[3][0], GLX_RGBA_TYPE, 0, GL_TRUE); if (!glxContext) { fprintf(stderr, "OGL Window: glXCreateContextWithConfig() failed\n"); exit (1); } if (!glXMakeCurrent(pDisplay, glxPbuffer, glxContext)) { fprintf (stderr, "initPbuffer: glXMakeCurrent Failed\n"); exit(1); } glFinish(); currentPbufferComponents = 4; free (iAttribList); static_pbuffers_initialized = true;}boolOGLWindow::bindPbuffer(unsigned int width, unsigned int height, unsigned int numOutputs, unsigned int numComponents) { /* Sadly, Linux doesn't seem to like rebinding a ** context to a different format pbuffer. So ** we just run everything in a float4 pbuffer. */ if (width > PBUFFER_WIDTH || height > PBUFFER_HEIGHT) { fprintf (stderr, "Pbuffer not big enough\n"); fprintf (stderr, "User requested %d x %d\n", width, height); exit(1); } if (numOutputs > 1) { fprintf (stderr, "Don't support multiple output on Linux yet\n"); exit(1); } return true;#if 0 static const int pbAttribList[] = { GLX_PRESERVED_CONTENTS, GL_TRUE, GLX_PBUFFER_WIDTH, 2048, GLX_PBUFFER_HEIGHT, 2048, 0 }; if (currentPbufferComponents == ncomponents) return; assert (ncomponents > 0 && ncomponents <= 4); glxPbuffer = glXCreatePbuffer(pDisplay, glxConfig[ncomponents-1][0], piAttribList[ncomponents-1]); if (glxPbuffer == 0) { fprintf (stderr, "Error: Could not create float%d pbuffer.\n", ncomponents); } if (!glXMakeCurrent(pDisplay, glxPbuffer, glxContext)) { fprintf (stderr, "bindPbuffer: glXMakeCurrent Failed\n"); exit(1); } glFinish(); currentPbufferComponents = ncomponents;#endif}OGLWindow::~OGLWindow() { // Switched everything to static#if 0 glXDestroyContext(pDisplay, glxContext); if (glxPbuffer) glXDestroyPbuffer(pDisplay, glxPbuffer); XDestroyWindow(pDisplay, glxWindow); XFreeColormap(pDisplay, cmap); XFree(visual); XCloseDisplay(pDisplay);#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -