📄 macvideo.cpp
字号:
{ GetPort (&portSave); // save current port SetPort ((GrafPtr) GetWindowPort (window)); // set port to the current window // set parameters for Carbon SetupGL pWindowInfo->glInfo.fAcceleratedMust = false; // must renderer be accelerated? pWindowInfo->glInfo.VRAM = 0 * 1048576; // minimum VRAM (if not zero this is always required) pWindowInfo->glInfo.textureRAM = 0 * 1048576; // minimum texture RAM (if not zero this is always required) pWindowInfo->glInfo.fDraggable = true; // is this a draggable window pWindowInfo->glInfo.fmt = 0; // output pixel format i = 0; // first attribute in array pWindowInfo->glInfo.aglAttributes [i++] = AGL_RGBA; // RGB + Alpha pixels pWindowInfo->glInfo.aglAttributes [i++] = AGL_DOUBLEBUFFER; // doble buffered context pWindowInfo->glInfo.aglAttributes [i++] = AGL_ACCELERATED; // require hardware acceleration pWindowInfo->glInfo.aglAttributes [i++] = AGL_NO_RECOVERY; // 10.0.4 has problems with the GL (disregards UNPACK_ROW_LENGTH) resulting from using no recovery // normally we would use no recovery to ensure the minimum pixel size textures are stored by GL. pWindowInfo->glInfo.aglAttributes [i++] = AGL_NONE; // end parameter list BuildGLonWindow (window, &(pWindowInfo->aglContext), &(pWindowInfo->glInfo), NULL); // build opengl context for our window if (!pWindowInfo->aglContext) // if could not create context DestroyGLFromWindow (&pWindowInfo->aglContext, &pWindowInfo->glInfo); // ensure context is destroyed correctly else // we have a valid context { GLint swap = 0; // swap interval (i.e., VBL sync) setting 1 = sync, 0 = no sync Rect rectPort; // window port rectangle long width = pWindowInfo->imageWidth, height = pWindowInfo->imageHeight; // image width and height GDHandle device; // GDevice to find the constrain the window to Rect deviceRect, availRect, rect; // rect of device which window is on (mostly, area wise at least). avialable area for window (minus dock and menu if req), working rect GetWindowGreatestAreaDevice (window, kWindowContentRgn, &device, &deviceRect); // find device the window is mostly on GetAvailableWindowPositioningBounds (device, &availRect); // get the geretest available area for te windoew (mminus doc and menu if applicable) if (width > (availRect.right - availRect.left)) // adjust window width if it is greater than available area (orginally set to image width, see above) width = (availRect.right - availRect.left); if (height > (availRect.bottom - availRect.top)) // adjust window height if it is greater than available area (orginally set to image width, see above) height = (availRect.bottom - availRect.top); SizeWindow (window, (short) width, (short) height, true); // size the window to new width and height ConstrainWindowToScreen(window, kWindowStructureRgn, kWindowConstrainMayResize, NULL, &rect); // ensure window structure region is on the screen GetWindowPortBounds (window, &rectPort); // get port rect for viewport reset aglSetCurrentContext (pWindowInfo->aglContext); // set our GL context to this one aglUpdateContext (pWindowInfo->aglContext); // update the context to account for the resize InvalWindowRect (window, &rectPort); // inval the entire window to ensure we get a redraw glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top); // reset viewport to entier window area aglSetInteger (pWindowInfo->aglContext, AGL_SWAP_INTERVAL, &swap); // set swap interval to account for vbl syncing or not // set correct texture target // if building on 10.0 or 9 this will be undefined #ifdef GL_TEXTURE_RECTANGLE_EXT if (pWindowInfo->fNPOTTextures) textureTarget = GL_TEXTURE_RECTANGLE_EXT; #endif // Set texture mapping parameters glEnable (textureTarget); // enable texturing glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // set clear color buffer to dark gray glClear (GL_COLOR_BUFFER_BIT); // clear just to color buffer aglSwapBuffers (pWindowInfo->aglContext); // swap the cleared buffer to front //GetFNum ("\pMonaco", &fNum); // get font number for named font //pWindowInfo->fontList = BuildFontGL (pWindowInfo->aglContext, fNum, normal, 9); // build display list for fonts for this context (see aglString for more info) // if we can use texture rectangle // if building on 10.0 or 9 this will be undefined #ifdef GL_TEXTURE_RECTANGLE_EXT if (pWindowInfo->fNPOTTextures) glEnable(GL_TEXTURE_RECTANGLE_EXT); #endif if (pWindowInfo->fAGPTexturing) glTextureRangeAPPLE(textureTarget, pWindowInfo->textureHeight * pWindowInfo->textureWidth * (pWindowInfo->imageDepth >> 3), pWindowInfo->pImageBuffer); glPixelStorei (GL_UNPACK_ROW_LENGTH, pWindowInfo->textureWidth); // set image width in groups (pixels), accounts for border this ensures proper image alignment row to row // get number of textures x and y // extract the number of horiz. textures needed to tile image pWindowInfo->textureX = GetTextureNumFromTextureDim (pWindowInfo->textureWidth, pWindowInfo->maxTextureSize, pWindowInfo->fOverlapTextures, pWindowInfo->fNPOTTextures); // extract the number of horiz. textures needed to tile image pWindowInfo->textureY = GetTextureNumFromTextureDim (pWindowInfo->textureHeight, pWindowInfo->maxTextureSize, pWindowInfo->fOverlapTextures, pWindowInfo->fNPOTTextures); pWindowInfo->pTextureName = (GLuint *) NewPtrClear ((long) sizeof (GLuint) * pWindowInfo->textureX * pWindowInfo->textureY); // allocate storage for texture name lists glGenTextures (pWindowInfo->textureX * pWindowInfo->textureY, pWindowInfo->pTextureName); // generate textures names need to support tiling { long x, y, k = 0, offsetY, offsetX = 0, currWidth, currHeight; // texture iterators, texture name iterator, image offsets for tiling, current texture width and height for (x = 0; x < pWindowInfo->textureX; x++) // for all horizontal textures { currWidth = GetNextTextureSize (pWindowInfo->textureWidth - offsetX, pWindowInfo->maxTextureSize, pWindowInfo->fNPOTTextures); // use remaining to determine next texture size // (basically greatest power of 2 which fits into remaining space) offsetY = 0; // reset vertical offest for every column for (y = 0; y < pWindowInfo->textureY; y++) // for all vertical textures { // buffer pointer is at base + rows * row size + columns unsigned char * pBuffer = pWindowInfo->pImageBuffer + offsetY * pWindowInfo->textureWidth * (pWindowInfo->imageDepth >> 3) + offsetX * (pWindowInfo->imageDepth >> 3); currHeight = GetNextTextureSize (pWindowInfo->textureHeight - offsetY, pWindowInfo->maxTextureSize, pWindowInfo->fNPOTTextures); // use remaining to determine next texture size glBindTexture (textureTarget, pWindowInfo->pTextureName[k++]); if (pWindowInfo->fAGPTexturing) { glTexParameterf (textureTarget, GL_TEXTURE_PRIORITY, 0.0f); // AGP texturing glTexParameteri (textureTarget, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE); } else glTexParameterf (textureTarget, GL_TEXTURE_PRIORITY, 1.0f); #ifdef GL_UNPACK_CLIENT_STORAGE_APPLE if (pWindowInfo->fClientTextures) glPixelStorei (GL_UNPACK_CLIENT_STORAGE_APPLE, 1); else glPixelStorei (GL_UNPACK_CLIENT_STORAGE_APPLE, 0); #endif glTexParameteri (textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (textureTarget, GL_TEXTURE_WRAP_S, gpOpenGLCaps->edgeClampParam); glTexParameteri (textureTarget, GL_TEXTURE_WRAP_T, gpOpenGLCaps->edgeClampParam); glReportError (); // report any errors so far glTexImage2D (textureTarget, 0, GL_RGBA, currWidth, currHeight, 0, GL_BGRA_EXT, pWindowInfo->imageDepth == 32 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_SHORT_1_5_5_5_REV, pBuffer); // texture with current width and height at pBuffer location in image buffer with image size as GL_UNPACK_ROW_LENGTH glReportError (); // report any errors offsetY += currHeight - 2 * pWindowInfo->fOverlapTextures; // offset in for the amount of texture used, // since we are overlapping the effective texture used is 2 texels less than texture width } offsetX += currWidth - 2 * pWindowInfo->fOverlapTextures; // offset in for the amount of texture used, // since we are overlapping the effective texture used is 2 texels less than texture width } } if (false == pWindowInfo->fClientTextures) // MUST preserve the buffer if texturing from client memory { DisposePtr ((Ptr) pWindowInfo->pImageBuffer); // or image buffer pWindowInfo->pImageBuffer = NULL; } } SetPort (portSave); //reset port } return noErr; // we done}// ---------------------------------// Handle updating context for window moves and resizingOSStatus ResizeMoveGLWindow (WindowRef window){ OSStatus err = noErr; // no errors to start Rect rectPort; // new port rect pRecImage pWindowInfo = (pRecImage) GetWRefCon (window); // get GL info; if (window && pWindowInfo) // if we have a window { GetWindowPortBounds (window, &rectPort); pWindowInfo->zoomX = (float) (rectPort.right - rectPort.left) / (float) pWindowInfo->imageWidth; pWindowInfo->zoomY = (float) (rectPort.bottom - rectPort.top) / (float) pWindowInfo->imageHeight; if (!aglUpdateContext (pWindowInfo->aglContext)) // update the context to ensure gl knows about the move or resize aglReportError (); // report any error with update context if (noErr != err) ReportErrorNum ("ResizeMoveGLWindow error with InvalWindowRect on window: ", err); // should not get erro here, but who knows err = InvalWindowRect (window, &rectPort); } else err = paramErr; // bad window return err; // return any error }// ---------------------------------// main GL drawing routine, should be valid window passed in (will setupGL if require). Draw imagevoid DrawGL (WindowRef window){ Rect rectPort; // rectangle for port pRecImage pWindowInfo; // the gl info for the target window long width, height; // width and height or the port and the row of the raster position long effectiveTextureMod = 0; // texture size modification (inset) to account for borders long x, y, k = 0, offsetY, offsetX = 0, currTextureWidth, currTextureHeight; GLenum textureTarget = GL_TEXTURE_2D; if (NULL == window) // if we do not have a window return; // drop out pWindowInfo = (pRecImage) GetWRefCon (window); // get the gl info for the window if (NULL == pWindowInfo) // if this is non-existant return; // then drop out if (NULL == pWindowInfo->aglContext) // try to buld the context if we don't have one (safety check) BuildGLForWindow (window); if (NULL == pWindowInfo->aglContext) // if we still don't have one then drop out return; if (pWindowInfo->fOverlapTextures) effectiveTextureMod = 2; // if we overlap then we need to inset the textures passed to the drawing code // set texture target#ifdef GL_TEXTURE_RECTANGLE_EXT if (pWindowInfo->fNPOTTextures) textureTarget = GL_TEXTURE_RECTANGLE_EXT;#endif 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 GetWindowPortBounds (window, &rectPort); // get the current port (window) bounds width = rectPort.right - rectPort.left; // find width height = rectPort.bottom - rectPort.top; // and height glViewport (0, 0, width, height); // set the viewport to cover entire window glMatrixMode (GL_PROJECTION); // set projection matrix glLoadIdentity (); // to indetity glMatrixMode (GL_MODELVIEW); // set modelview matrix glLoadIdentity (); // to identity glReportError (); // report any GL errors so far // set the model view matrix for an orthographic view scaled to one screen pixel equal image pixel (independent of image zoom) glScalef (2.0f / width, -2.0f / height, 1.0f); // scale to port per pixel scale //glTranslatef (pWindowInfo->centerX, pWindowInfo->centerY, 0.0f); // translate for image movement //glRotatef (0.0f, 0.0f, 0.0f, 1.0f); // ratate matrix for image rotation glReportError (); // report any GL errors glClear (GL_COLOR_BUFFER_BIT); // clear the color buffer before drawing // draw image glEnable (textureTarget); // enable texturing glColor3f (1.0f, 1.0f, 1.0f); // white polygons // offset x and y are used to draw the polygon and need to represent the texture effective edges (without borders) // so walk the texture size images adjusting for each border for (x = 0; x < pWindowInfo->textureX; x++) // for all horizontal textures { // use remaining to determine next texture size currTextureWidth = GetNextTextureSize (pWindowInfo->textureWidth - offsetX, pWindowInfo->maxTextureSize, pWindowInfo->fNPOTTextures) - effectiveTextureMod; // current effective texture width for drawing offsetY = 0; // start at top for (y = 0; y < pWindowInfo->textureY; y++) // for a complete column { // use remaining to determine next texture size currTextureHeight = GetNextTextureSize (pWindowInfo->textureHeight - offsetY, pWindowInfo->maxTextureSize, pWindowInfo->fNPOTTextures) - effectiveTextureMod; // effective texture height for drawing glBindTexture(textureTarget, pWindowInfo->pTextureName[k++]); // work through textures in same order as stored, setting each texture name as current in turn if (!pWindowInfo->fAGPTexturing) glTexSubImage2D(textureTarget, 0, 0, 0, currTextureWidth, currTextureHeight, GL_BGRA, pWindowInfo->imageDepth == 32 ? GL_UNSIGNED_INT_8_8_8_8_REV : GL_UNSIGNED_SHORT_1_5_5_5_REV, pWindowInfo->pImageBuffer); glReportError (); // report any errors { float endX = pWindowInfo->fTileTextures ? currTextureWidth + offsetX : pWindowInfo->imageWidth; float endY = pWindowInfo->fTileTextures ? currTextureHeight + offsetY : pWindowInfo->imageHeight; float startXDraw = (offsetX - pWindowInfo->imageWidth * 0.5f) * pWindowInfo->zoomX; // left edge of poly: offset is in image local coordinates convert to world coordinates float endXDraw = (endX - pWindowInfo->imageWidth * 0.5f) * pWindowInfo->zoomX; // right edge of poly: offset is in image local coordinates convert to world coordinates float startYDraw = (offsetY - pWindowInfo->imageHeight * 0.5f) * pWindowInfo->zoomY; // top edge of poly: offset is in image local coordinates convert to world coordinates float endYDraw = (endY - pWindowInfo->imageHeight * 0.5f) * pWindowInfo->zoomY; // bottom edge of poly: offset is in image local coordinates convert to world coordinates float texOverlap = pWindowInfo->fOverlapTextures ? 1.0f : 0.0f; // size of texture overlap, switch based on whether we are using overlap or not float startXTexCoord = texOverlap / (currTextureWidth + 2.0f * texOverlap); // texture right edge coordinate (stepped in one pixel for border if required) float endXTexCoord = 1.0f - startXTexCoord; // texture left edge coordinate (stepped in one pixel for border if required) float startYTexCoord = texOverlap / (currTextureHeight + 2.0f * texOverlap); // texture top edge coordinate (stepped in one pixel for border if required) float endYTexCoord = 1.0f - startYTexCoord; // texture bottom edge coordinate (stepped in one pixel for border if required) if (pWindowInfo->fNPOTTextures) { startXTexCoord = texOverlap; // texture right edge coordinate (stepped in one pixel for border if required) endXTexCoord = currTextureWidth + texOverlap; // texture left edge coordinate (stepped in one pixel for border if required) startYTexCoord = texOverlap; // texture top edge coordinate (stepped in one pixel for border if required) endYTexCoord = currTextureHeight + texOverlap; // texture bottom edge coordinate (stepped in one pixel for border if required) } if (endX > (pWindowInfo->imageWidth + 0.5)) // handle odd image sizes, (+0.5 is to ensure there is no fp resolution problem in comparing two fp numbers) { endXDraw = (pWindowInfo->imageWidth * 0.5f) * pWindowInfo->zoomX; // end should never be past end of image, so set it there if (pWindowInfo->fNPOTTextures) endXTexCoord -= 1.0f; else endXTexCoord = 1.0f - 2.0f * startXTexCoord; // for the last texture in odd size images there are two texels of padding so step in 2 } if (endY > (pWindowInfo->imageHeight + 0.5f)) // handle odd image sizes, (+0.5 is to ensure there is no fp resolution problem in comparing two fp numbers) { endYDraw = (pWindowInfo->imageHeight * 0.5f) * pWindowInfo->zoomY; // end should never be past end of image, so set it there if (pWindowInfo->fNPOTTextures) endYTexCoord -= 1.0f; else endYTexCoord = 1.0f - 2.0f * startYTexCoord; // for the last texture in odd size images there are two texels of padding so step in 2 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -