//macscreen.cpp //mac-specific code to access the screen device #include #include #include #include "screen.h" #include "config.h" #include "error.h" #include "textures.h" AGLContext gOpenGLContext=NULL; AGLContext SetupAGL( AGLDrawable window,GLint *attrib,int width, int height) { AGLPixelFormat format; AGLContext context; GLboolean ok; GLint attrib2[256]; GDHandle screen; if(window) screen=GetGWorldDevice((GWorldPtr)window); else screen=DMGetFirstScreenDevice(true); if(window==NULL) { int i=0; while(attrib[i]!=AGL_NONE) attrib2[i++]=attrib[i]; attrib2[i++]=AGL_FULLSCREEN; //attrib2[i++]=AGL_NO_RECOVERY; attrib2[i++]=AGL_NONE; attrib=attrib2; } // Choose an rgb pixel format format = aglChoosePixelFormat( &screen, 1, attrib ); if ( format == NULL ) { printf("aglChoosePixelFormat: %s\n",aglErrorString(aglGetError())); return NULL; } // Create an AGL context context = aglCreateContext( format, gOpenGLContext ); if ( context == NULL ) { printf("aglCreateContext: %s\n",aglErrorString(aglGetError())); return NULL; } if(window){ ok = aglSetDrawable(context,window); if ( !ok ) { printf("aglSetDrawable: %s\n",aglErrorString(aglGetError())); return NULL; } } else{ ok = aglSetFullScreen (context,width,height,75,0); if ( !ok ) { ok = aglSetFullScreen (context,640,480,75,0); if ( !ok ) { printf("aglSetFullScreen: %s\n",aglErrorString(aglGetError())); return NULL; } } } // Make the context the current context ok = aglSetCurrentContext( context ); if ( !ok ) { printf("aglSetCurrentContext: %s\n",aglErrorString(aglGetError())); return NULL; } // The pixel format is no longer needed so get rid of it aglDestroyPixelFormat( format ); return context; } //Initialize an OpenGL context using AGL void InitGLContext() { CGrafPtr theScreen=NULL; //is fullscreen mode enabled? if(gConfig->fullscreen) theScreen=NULL; else { //get a Window Context Rect boundsRect; if(gConfig->windowY<40) gConfig->windowY=40; SetRect(&boundsRect,gConfig->windowX,gConfig->windowY,gConfig->windowX+gConfig->screenXSize,gConfig->windowY+gConfig->screenYSize); WindowRef win=NewCWindow(0,&boundsRect,"\pRedline",true,0,(WindowRef)-1L,false,0); if(!RectInRgn(&boundsRect,GetGrayRgn())) MoveWindow(win,40,40,true); theScreen=GetWindowPort(win); SetPort(theScreen); GetPortBounds(theScreen,&boundsRect); Pattern black; GetQDGlobalsBlack(&black); FillRect(&boundsRect,&black); HIWindowFlush(FrontWindow()); } // Setup the OpenGL context AGLContext ctx; if(gConfig->fsaa) { GLint attrib[] = { AGL_RGBA, AGL_PIXEL_SIZE, gConfig->color32Bit?32:16,AGL_NO_RECOVERY,AGL_DOUBLEBUFFER, AGL_STENCIL_SIZE, 8,AGL_SAMPLE_BUFFERS_ARB,1,AGL_SAMPLES_ARB,gConfig->fsaa, AGL_NONE}; // GLint attrib[] = { AGL_RGBA, AGL_PIXEL_SIZE, gConfig->color32Bit?32:16,AGL_DOUBLEBUFFER, AGL_STENCIL_SIZE, 8,AGL_SAMPLE_BUFFERS_ARB,1,AGL_SAMPLES_ARB,gConfig->fsaa, AGL_NONE}; ctx=SetupAGL((AGLDrawable)theScreen,attrib,gConfig->screenXSize,gConfig->screenYSize); } else { GLint attrib[] = { AGL_RGBA, AGL_PIXEL_SIZE, gConfig->color32Bit?32:16,AGL_NO_RECOVERY,AGL_DOUBLEBUFFER, AGL_STENCIL_SIZE, 8, AGL_NONE}; // GLint attrib[] = { AGL_RGBA, AGL_PIXEL_SIZE, gConfig->color32Bit?32:16,AGL_DOUBLEBUFFER, AGL_STENCIL_SIZE, 8, AGL_NONE}; ctx=SetupAGL((AGLDrawable)theScreen,attrib,gConfig->screenXSize,gConfig->screenYSize); } if(!ctx) { if(gConfig->fullscreen) { gConfig->fullscreen=false; InitGLContext(); } else FailWithErrorString("Couldn't Create Screen"); } else { if(gOpenGLContext) aglDestroyContext(gOpenGLContext); gOpenGLContext=ctx; } } static int numberForKey( CFDictionaryRef desc, CFStringRef key ) { CFNumberRef value; int num = 0; if ( (value = (CFNumberRef)CFDictionaryGetValue(desc, key)) == NULL ) return 0; CFNumberGetValue(value, kCFNumberIntType, &num); return num; } void ScreenGetModes() { CFArrayRef modeList; CFIndex i, cnt; gVideoNumModes=0; modeList = CGDisplayAvailableModes(kCGDirectMainDisplay); if ( modeList == NULL ) { printf( "Display is invalid\n" ); exit(1); } cnt = CFArrayGetCount(modeList); for ( i = 0; i < cnt; ++i ) { CFDictionaryRef desc = (CFDictionaryRef)CFArrayGetValueAtIndex(modeList, i); int depth=numberForKey(desc, kCGDisplayBitsPerPixel); if(depth==32&&gVideoNumModes=60) gVideoModes[j].freq=freq; exists=true; } if(!exists) { gVideoModes[gVideoNumModes].height=height; gVideoModes[gVideoNumModes].width=width; gVideoModes[gVideoNumModes].freq=freq; gVideoNumModes++; } } } for(int i=0;i= dMaxVRAM) // find card with max VRAM dMaxVRAM = dVRAM; // store max } info = aglNextRendererInfo(info); inum++; } // aglDestroyRendererInfo(head_info); return dVRAM; } int ScreenSupportsTextureCompression() { static int result=-1; if(result==-1) { char* extensions=(char*)glGetString(GL_EXTENSIONS); result=strstr(extensions,"GL_EXT_texture_compression_s3tc")?true:false; long resp; Gestalt(gestaltSystemVersion,&resp); if(resp<0x00001030) { //GeForce Texture compression seems buggy in 10.2.8 char* renderer=(char*)glGetString(GL_RENDERER); if (strstr(renderer,"GeForce")) result=false; } } return result; } int ScreenSupportsAnisotropicFiltering() { static int result=-1; if(result==-1) { char* extensions=(char*)glGetString(GL_EXTENSIONS); result=strstr(extensions,"GL_EXT_texture_filter_anisotropic")?true:false; char* renderer=(char*)glGetString(GL_RENDERER); //GeForce 5200 bug if (strstr (renderer, "NV34MAP") || (strstr (renderer , "GeForce") && strstr (renderer, "5200"))) result=false; } return result; } int ScreenSupports3DTextures() { static int result=-1; if(result==-1) { /* char* extensions=(char*)glGetString(GL_EXTENSIONS); result=strstr(extensions,"GL_EXT_texture3D")?true:false; */ result=true; //built-in in GL 1.2 or higher. char* renderer=(char*)glGetString(GL_RENDERER); printf("Renderer: %s\n",renderer); //GeForce 2 only has software 3d textures (? - according to unity) if (strstr (renderer, "GeForce") && !(strstr (renderer , "TI") || strstr (renderer, "FX"))) result=false; //same with Rage128 if (strstr (renderer, "Rage") && strstr (renderer, "128")) result=false; } return result; } int ScreenSupportsBlendColor() { static int result=-1; if(result==-1) { char* extensions=(char*)glGetString(GL_EXTENSIONS); result=strstr(extensions,"GL_ARB_imaging")?true:false; } return result; } int ScreenNoBigTextures() { static int result=-1; if(result==-1) result=GetVRAMSize()<=1024*1024*8; return result; } int ScreenNoWindow() { static int result=-1; if(result==-1) { long resp; Gestalt(gestaltSystemVersion,&resp); result=(resp<0x00001030); } return result; }