//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #if defined( TORQUE_SDL ) && !defined( TORQUE_DEDICATED ) #include "gfx/gfxCubemap.h" #include "gfx/screenshot.h" #include "gfx/gl/gfxGLDevice.h" #include "gfx/gl/gfxGLEnumTranslate.h" #include "gfx/gl/gfxGLVertexBuffer.h" #include "gfx/gl/gfxGLPrimitiveBuffer.h" #include "gfx/gl/gfxGLTextureTarget.h" #include "gfx/gl/gfxGLWindowTarget.h" #include "gfx/gl/gfxGLTextureManager.h" #include "gfx/gl/gfxGLTextureObject.h" #include "gfx/gl/gfxGLCubemap.h" #include "gfx/gl/gfxGLCardProfiler.h" #include "windowManager/sdl/sdlWindow.h" #include "platform/platformGL.h" #include "SDL.h" extern void loadGLCore(); extern void loadGLExtensions(void* context); void EnumerateVideoModes(Vector& outModes) { int count = SDL_GetNumDisplayModes( 0 ); if( count < 0) { AssertFatal(0, ""); return; } SDL_DisplayMode mode; for(int i = 0; i < count; ++i) { SDL_GetDisplayMode( 0, i, &mode); GFXVideoMode outMode; outMode.resolution.set( mode.w, mode.h ); outMode.refreshRate = mode.refresh_rate; // BBP = 32 for some reason the engine knows it should be 32, but then we // add some extra code to break what the engine knows. //outMode.bitDepth = SDL_BYTESPERPIXEL( mode.format ); // sets bitdepths to 4 //outMode.bitDepth = SDL_BITSPERPIXEL(mode.format); // sets bitdepth to 24 // hardcoded magic numbers ftw // This value is hardcoded in DX, probably to avoid the shenanigans going on here outMode.bitDepth = 32; outMode.wideScreen = (mode.w / mode.h) > (4 / 3); outMode.fullScreen = true; outModes.push_back( outMode ); } } void GFXGLDevice::enumerateAdapters( Vector &adapterList ) { AssertFatal( SDL_WasInit(SDL_INIT_VIDEO), ""); PlatformGL::init(); // for hints about context creation // Create a dummy window & openGL context so that gl functions can be used here SDL_Window* tempWindow = SDL_CreateWindow( "", // window title SDL_WINDOWPOS_UNDEFINED, // initial x position SDL_WINDOWPOS_UNDEFINED, // initial y position 640, // width, in pixels 480, // height, in pixels SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN // flags - see below ); if (!tempWindow) { const char* err = SDL_GetError(); Con::printf(err); AssertFatal(0, err); return; } SDL_ClearError(); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1); SDL_GLContext tempContext = SDL_GL_CreateContext( tempWindow ); if( !tempContext ) { const char *err = SDL_GetError(); Con::printf( err ); AssertFatal(0, err ); return; } SDL_ClearError(); SDL_GL_MakeCurrent( tempWindow, tempContext ); const char *err = SDL_GetError(); if( err && err[0] ) { Con::printf( err ); AssertFatal(0, err ); } // Init GL loadGLCore(); loadGLExtensions(tempContext); //check minimun Opengl 3.3 int major, minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); if( major < 3 || ( major == 3 && minor < 3 ) ) { return; } //check for required extensions if (!gglHasExtension(ARB_texture_cube_map_array)) { Con::warnf("Adapater supports OpenGL 3.3 but doesnt support GL_ARB_texture_cube_map_array"); return; } if (!gglHasExtension(ARB_gpu_shader5)) { Con::warnf("Adapater supports OpenGL 3.3 but doesnt support GL_ARB_gpu_shader5"); return; } GFXAdapter *toAdd = new GFXAdapter; toAdd->mIndex = 0; const char* renderer = (const char*) glGetString( GL_RENDERER ); AssertFatal( renderer != NULL, "GL_RENDERER returned NULL!" ); if (renderer) { dStrcpy(toAdd->mName, renderer, GFXAdapter::MaxAdapterNameLen); dStrcat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen); } else dStrcpy(toAdd->mName, "OpenGL", GFXAdapter::MaxAdapterNameLen); toAdd->mType = OpenGL; toAdd->mShaderModel = 0.f; toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance; // Enumerate all available resolutions: EnumerateVideoModes(toAdd->mAvailableModes); // Add to the list of available adapters. adapterList.push_back(toAdd); // Cleanup window & open gl context SDL_DestroyWindow( tempWindow ); SDL_GL_DeleteContext( tempContext ); } void GFXGLDevice::enumerateVideoModes() { mVideoModes.clear(); EnumerateVideoModes(mVideoModes); } void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window ) { AssertFatal(window, "GFXGLDevice::init - no window specified, can't init device without a window!"); PlatformWindowSDL* sdlWindow = dynamic_cast(window); AssertFatal(sdlWindow, "Window is not a valid PlatformWindowSDL object"); // Create OpenGL context mContext = PlatformGL::CreateContextGL( sdlWindow ); PlatformGL::MakeCurrentGL( sdlWindow, mContext ); loadGLCore(); loadGLExtensions(mContext); // It is very important that extensions be loaded before we call initGLState() initGLState(); mProjectionMatrix.identity(); mInitialized = true; deviceInited(); } bool GFXGLDevice::beginSceneInternal() { mCanCurrentlyRender = true; return true; } U32 GFXGLDevice::getTotalVideoMemory() { return getTotalVideoMemory_GL_EXT(); } //------------------------------------------------------------------------------ GFXWindowTarget *GFXGLDevice::allocWindowTarget( PlatformWindow *window ) { GFXGLWindowTarget* ggwt = new GFXGLWindowTarget(window, this); //first window if (!mContext) { init(window->getVideoMode(), window); ggwt->mSecondaryWindow = false; } else ggwt->mSecondaryWindow = true; ggwt->registerResourceWithDevice(this); ggwt->mContext = mContext; return ggwt; } GFXFence* GFXGLDevice::_createPlatformSpecificFence() { return NULL; } //----------------------------------------------------------------------------- void GFXGLWindowTarget::_WindowPresent() { SDL_GL_SwapWindow( static_cast( getWindow() )->getSDLWindow() ); } void GFXGLWindowTarget::_teardownCurrentMode() { } void GFXGLWindowTarget::_setupNewMode() { } void GFXGLWindowTarget::_makeContextCurrent() { PlatformGL::MakeCurrentGL(mWindow, mContext); } #endif