Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/DeviceBuilder.cpp
2 views
/*1Copyright (C) 2003 Rice196423This program is free software; you can redistribute it and/or4modify it under the terms of the GNU General Public License5as published by the Free Software Foundation; either version 26of the License, or (at your option) any later version.78This program is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11GNU General Public License for more details.1213You should have received a copy of the GNU General Public License14along with this program; if not, write to the Free Software15Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.1617*/1819#include "osal_opengl.h"2021#include "DeviceBuilder.h"22#include "FrameBuffer.h"23#include "OGLCombiner.h"24#include "OGLDebug.h"25#include "OGLExtRender.h"26#include "OGLGraphicsContext.h"27#include "OGLTexture.h"28#if SDL_VIDEO_OPENGL29#include "OGLCombinerNV.h"30#include "OGLCombinerTNT2.h"31#include "OGLExtensions.h"32#include "OGLFragmentShaders.h"33#elif SDL_VIDEO_OPENGL_ES234#include "OGLES2FragmentShaders.h"35#endif3637//========================================================================38CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL;39SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE;40SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE;4142CDeviceBuilder* CDeviceBuilder::GetBuilder(void)43{44if( m_pInstance == NULL )45CreateBuilder(m_deviceType);4647return m_pInstance;48}4950void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type)51{52if( type != m_deviceType && m_pInstance != NULL )53{54DeleteBuilder();55}5657CDeviceBuilder::m_deviceType = type;58switch(type)59{60case OGL_DEVICE:61case OGL_1_1_DEVICE:62case OGL_1_2_DEVICE:63case OGL_1_3_DEVICE:64case OGL_1_4_DEVICE:65case OGL_1_4_V2_DEVICE:66case OGL_TNT2_DEVICE:67case NVIDIA_OGL_DEVICE:68case OGL_FRAGMENT_PROGRAM:69CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE;70break;71default:72break;73}74}7576SupportedDeviceType CDeviceBuilder::GetDeviceType(void)77{78return CDeviceBuilder::m_deviceType;79}8081SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void)82{83return CDeviceBuilder::m_deviceGeneralType;84}8586CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type)87{88if( m_pInstance == NULL )89{90switch( type )91{92case OGL_DEVICE:93case OGL_1_1_DEVICE:94case OGL_1_2_DEVICE:95case OGL_1_3_DEVICE:96case OGL_1_4_DEVICE:97case OGL_1_4_V2_DEVICE:98case OGL_TNT2_DEVICE:99case NVIDIA_OGL_DEVICE:100case OGL_FRAGMENT_PROGRAM:101m_pInstance = new OGLDeviceBuilder();102break;103default:104DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type");105exit(1);106}107108SAFE_CHECK(m_pInstance);109}110111return m_pInstance;112}113114void CDeviceBuilder::DeleteBuilder(void)115{116delete m_pInstance;117m_pInstance = NULL;118}119120CDeviceBuilder::CDeviceBuilder() :121m_pRender(NULL),122m_pGraphicsContext(NULL),123m_pColorCombiner(NULL),124m_pAlphaBlender(NULL)125{126}127128CDeviceBuilder::~CDeviceBuilder()129{130DeleteGraphicsContext();131DeleteRender();132DeleteColorCombiner();133DeleteAlphaBlender();134}135136void CDeviceBuilder::DeleteGraphicsContext(void)137{138if( m_pGraphicsContext != NULL )139{140delete m_pGraphicsContext;141CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL;142}143144SAFE_DELETE(g_pFrameBufferManager);145}146147void CDeviceBuilder::DeleteRender(void)148{149if( m_pRender != NULL )150{151delete m_pRender;152CRender::g_pRender = m_pRender = NULL;153CRender::gRenderReferenceCount = 0;154}155}156157void CDeviceBuilder::DeleteColorCombiner(void)158{159if( m_pColorCombiner != NULL )160{161delete m_pColorCombiner;162m_pColorCombiner = NULL;163}164}165166void CDeviceBuilder::DeleteAlphaBlender(void)167{168if( m_pAlphaBlender != NULL )169{170delete m_pAlphaBlender;171m_pAlphaBlender = NULL;172}173}174175176//========================================================================177178CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void)179{180if( m_pGraphicsContext == NULL )181{182m_pGraphicsContext = new COGLGraphicsContext();183SAFE_CHECK(m_pGraphicsContext);184CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext;185}186187g_pFrameBufferManager = new FrameBufferManager;188return m_pGraphicsContext;189}190191CRender * OGLDeviceBuilder::CreateRender(void)192{193if( m_pRender == NULL )194{195if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )196{197DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");198m_pRender = NULL;199SAFE_CHECK(m_pRender);200}201202COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext);203204if( context.m_bSupportMultiTexture )205{206// OGL extension render207m_pRender = new COGLExtRender();208}209else210{211// Basic OGL Render212m_pRender = new OGLRender();213}214SAFE_CHECK(m_pRender);215CRender::g_pRender = m_pRender;216}217218return m_pRender;219}220221CTexture * OGLDeviceBuilder::CreateTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage)222{223COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage);224if( txtr->m_pTexture == NULL )225{226delete txtr;227TRACE0("Cannot create new texture, out of video memory");228return NULL;229}230else231return txtr;232}233234CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender)235{236if( m_pColorCombiner == NULL )237{238if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )239{240DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");241}242else243{244m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting;245246#if SDL_VIDEO_OPENGL247248if (m_deviceType == NVIDIA_OGL_DEVICE && !bNvidiaExtensionsSupported)249{250DebugMessage(M64MSG_WARNING, "Your video card does not support Nvidia OpenGL extensions. Falling back to auto device.");251m_deviceType = OGL_DEVICE;252}253if( m_deviceType == OGL_DEVICE ) // Best fit254{255GLint maxUnit = 2;256COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);257glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&maxUnit);258OPENGL_CHECK_ERRORS;259260if( pcontext->IsExtensionSupported("GL_ARB_fragment_program") )261{262m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);263DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");264}265else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") ||266pcontext->IsExtensionSupported("GL_NV_register_combiners") )267{268m_pColorCombiner = new COGLColorCombinerNvidia(pRender);269DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: NVidia");270}271else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") )272{273m_pColorCombiner = new COGLColorCombinerTNT2(pRender);274DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");275}276else if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") ||277pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )278{279if( pcontext->IsExtensionSupported("GL_ARB_texture_env_crossbar") )280{281if( maxUnit > 2 )282{283m_pColorCombiner = new COGLColorCombiner4v2(pRender);284DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2");285}286else287{288m_pColorCombiner = new COGLColorCombiner4(pRender);289DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");290}291}292else293{294if( maxUnit > 2 )295{296m_pColorCombiner = new COGLColorCombiner4v2(pRender);297DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2 (w/o env crossbar)");298}299else300{301m_pColorCombiner = new COGLColorCombiner2(pRender);302DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");303}304}305}306else307{308m_pColorCombiner = new COGLColorCombiner(pRender);309DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");310}311}312else313{314switch(m_deviceType)315{316case OGL_1_1_DEVICE:317m_pColorCombiner = new COGLColorCombiner(pRender);318DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");319break;320case OGL_1_2_DEVICE:321case OGL_1_3_DEVICE:322m_pColorCombiner = new COGLColorCombiner2(pRender);323DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");324break;325case OGL_1_4_DEVICE:326m_pColorCombiner = new COGLColorCombiner4(pRender);327DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");328break;329case OGL_1_4_V2_DEVICE:330m_pColorCombiner = new COGLColorCombiner4v2(pRender);331DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 Version 2");332break;333case OGL_TNT2_DEVICE:334m_pColorCombiner = new COGLColorCombinerTNT2(pRender);335DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");336break;337case NVIDIA_OGL_DEVICE:338m_pColorCombiner = new COGLColorCombinerNvidia(pRender);339DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Nvidia");340break;341case OGL_FRAGMENT_PROGRAM:342m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);343DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");344break;345default:346break;347}348}349350#elif SDL_VIDEO_OPENGL_ES2351m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);352DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");353#endif354}355356SAFE_CHECK(m_pColorCombiner);357}358359return m_pColorCombiner;360}361362CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender)363{364if( m_pAlphaBlender == NULL )365{366m_pAlphaBlender = new COGLBlender(pRender);367SAFE_CHECK(m_pAlphaBlender);368}369370return m_pAlphaBlender;371}372373374375