📄 macvideo.cpp
字号:
} // do agl if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL { ReportError ("OpenGL not installed"); return noErr; } // we successfully passed the renderer check if ((!pcontextInfo->fDraggable && (numDevices == 1))) // not draggable on a single device pcontextInfo->fmt = aglChoosePixelFormat (&hGD, 1, pcontextInfo->aglAttributes); // get an appropriate pixel format else pcontextInfo->fmt = aglChoosePixelFormat (NULL, 0, pcontextInfo->aglAttributes); // get an appropriate pixel format aglReportError (); if (NULL == pcontextInfo->fmt) { ReportError("Could not find valid pixel format"); return noErr; } *paglContext = aglCreateContext (pcontextInfo->fmt, aglShareContext); // Create an AGL context if (AGL_BAD_MATCH == aglGetError()) *paglContext = aglCreateContext (pcontextInfo->fmt, 0); // unable to sahre context, create without sharing aglReportError (); if (NULL == *paglContext) { ReportError ("Could not create context"); return noErr; } if (!aglSetDrawable (*paglContext, GetWindowPort (pWindow))) // attach the CGrafPtr to the context return aglReportError (); if(!aglSetCurrentContext (*paglContext)) // make the context the current context return aglReportError (); SetPort (cgrafSave); return err;}#pragma mark -// functions (public) -------------------------------------------------------// DestroyGLFromWindow// Destroys context that waas allocated with BuildGLonWindow// Ouputs: *paglContext should be NULL on exitOSStatus DestroyGLFromWindow (AGLContext* paglContext, pstructGLWindowInfo pcontextInfo){ OSStatus err; if ((!paglContext) || (!*paglContext)) return paramErr; // not a valid context glFinish (); aglSetCurrentContext (NULL); err = aglReportError (); aglSetDrawable (*paglContext, NULL); err = aglReportError (); aglDestroyContext (*paglContext); err = aglReportError (); *paglContext = NULL; if (pcontextInfo->fmt) { aglDestroyPixelFormat (pcontextInfo->fmt); // pixel format is no longer valid err = aglReportError (); } pcontextInfo->fmt = 0; return err;}//-----------------------------------------------------------------------------------------------------------------------// GetWindowDevice// Inputs: a valid WindowPtr// Outputs: the GDHandle that that window is mostly on// returns the number of devices that the windows content touchesshort FindGDHandleFromWindow (WindowPtr pWindow, GDHandle * phgdOnThisDevice){ GrafPtr pgpSave; Rect rectWind, rectSect; long greatestArea, sectArea; short numDevices = 0; GDHandle hgdNthDevice; if (!pWindow || !phgdOnThisDevice) return 0; *phgdOnThisDevice = NULL; GetPort (&pgpSave); SetPortWindowPort (pWindow); GetWindowPortBounds (pWindow, &rectWind); LocalToGlobal ((Point*)& rectWind.top); // convert to global coordinates LocalToGlobal ((Point*)& rectWind.bottom); hgdNthDevice = GetDeviceList (); greatestArea = 0; // check window against all gdRects in gDevice list and remember // which gdRect contains largest area of window} while (hgdNthDevice) { if (TestDeviceAttribute (hgdNthDevice, screenDevice)) if (TestDeviceAttribute (hgdNthDevice, screenActive)) { // The SectRect routine calculates the intersection // of the window rectangle and this gDevice // rectangle and returns TRUE if the rectangles intersect, // FALSE if they don't. SectRect (&rectWind, &(**hgdNthDevice).gdRect, &rectSect); // determine which screen holds greatest window area // first, calculate area of rectangle on current device sectArea = (long) (rectSect.right - rectSect.left) * (rectSect.bottom - rectSect.top); if (sectArea > 0) numDevices++; if (sectArea > greatestArea) { greatestArea = sectArea; // set greatest area so far *phgdOnThisDevice = hgdNthDevice; // set zoom device } hgdNthDevice = GetNextDevice(hgdNthDevice); } } SetPort (pgpSave); return numDevices;}//--------------------------------------------------------------------------------------------// private// returns the largest power of 2 texture <= textureDimension// or in the case of texture rectangle returns the next texture size (can be non-power of two)static long GetNextTextureSize (long textureDimension, long maxTextureSize, Boolean textureRectangle){ long targetTextureSize = maxTextureSize; // start at max texture size if (textureRectangle) { if (textureDimension >= targetTextureSize) // the texture dimension is greater than the target texture size (i.e., it fits) return targetTextureSize; // return corresponding texture size else return textureDimension; // jusr return the dimension } else { do // while we have txture sizes check for texture value being equal or greater { if (textureDimension >= targetTextureSize) // the texture dimension is greater than the target texture size (i.e., it fits) return targetTextureSize; // return corresponding texture size } while (targetTextureSize >>= 1); // step down to next texture size smaller } return 0; // no textures fit so return zero}// ---------------------------------// returns the nuber of textures need to represent a size of textureDimension given// requirement for power of 2 textures as the maximum texture size// for the overlap case each texture effectively covers two less pixels so must iterate through using whole statementstatic long GetTextureNumFromTextureDim (long textureDimension, long maxTextureSize, Boolean texturesOverlap, Boolean textureRectangle) { // start at max texture size // loop through each texture size, removing textures in turn which are less than the remaining texture dimension // each texture has 2 pixels of overlap (one on each side) thus effective texture removed is 2 less than texture size long i = 0; // initially no textures long bitValue = maxTextureSize; // start at max texture size long texOverlapx2 = texturesOverlap ? 2 : 0; textureDimension -= texOverlapx2; // ignore texture border since we are using effective texure size (by subtracting 2 from the initial size) if (textureRectangle) { // count number of full textures while (textureDimension > (bitValue - texOverlapx2)) // while our texture dimension is greater than effective texture size (i.e., minus the border) { i++; // count a texture textureDimension -= bitValue - texOverlapx2; // remove effective texture size } // add one partial texture i++; } else { do { while (textureDimension >= (bitValue - texOverlapx2)) // while our texture dimension is greater than effective texture size (i.e., minus the border) { i++; // count a texture textureDimension -= bitValue - texOverlapx2; // remove effective texture size } } while ((bitValue >>= 1) > texOverlapx2); // step down to next texture while we are greater than two (less than 4 can't be used due to 2 pixel overlap) if (textureDimension > 0x0) // if any textureDimension is left there is an error, because we can't texture these small segments and in anycase should not have image pixels left ReportErrorNum ("GetTextureNumFromTextureDim error: Texture to small to draw, should not ever get here, texture size remaining:", textureDimension); } return i; // return textures counted} #pragma mark -// ==================================// public// disposes OpenGL context, and associated texture listOSStatus DisposeGLForWindow (WindowRef window){ if (window) { pRecImage pWindowInfo = (pRecImage) GetWRefCon (window); // get gl data stored in refcon SetWRefCon (window, 0); // ensure the refcon is not used again if (NULL == pWindowInfo) // if this is non-existant return paramErr; // then drop out if (NULL != pWindowInfo->aglContext) { aglSetCurrentContext (pWindowInfo->aglContext); // ensaure the context we are working with is set to current aglUpdateContext (pWindowInfo->aglContext); // ensaure the context we are working with is set to current glFinish (); // ensure all gl commands are complete glDeleteTextures (pWindowInfo->textureX * pWindowInfo->textureY, pWindowInfo->pTextureName); // delete the complete set of textures used for the window DestroyGLFromWindow (&pWindowInfo->aglContext, &pWindowInfo->glInfo); // preoperly destroy GL context and any associated structures pWindowInfo->aglContext = NULL; // ensure we don't use invlad context } if (NULL != pWindowInfo->pTextureName) { DisposePtr ((Ptr) pWindowInfo->pTextureName); // dispose of the allocate4d texture name storage pWindowInfo->pTextureName = NULL; // ensure we do not use it again } if (pWindowInfo->pImageBuffer) // MUST preserve the buffer if texturing from client memory { //DisposePtr ((Ptr) pWindowInfo->pImageBuffer); // or image buffer pWindowInfo->pImageBuffer = NULL; } DisposePtr ((Ptr) pWindowInfo); return noErr; // we are good to go } else return paramErr; // NULL window ref passed in}// ---------------------------------// builds the GL context and associated state for the window// loads image into a texture or textures// disposes of GWorld and image buffer when finished loading texturesOSStatus BuildGLForWindow (WindowRef window){ GrafPtr portSave = NULL; // port which is set on entrance to this routine pRecImage pWindowInfo = (pRecImage) GetWRefCon (window); // the info structure for the window stored in the refcon short i; // iterator GLenum textureTarget = GL_TEXTURE_2D; if (!pWindowInfo->aglContext) // if we get here and do not have a context built, build one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -