X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Frice_gles%2Fsrc%2FDeviceBuilder.cpp;fp=source%2Frice_gles%2Fsrc%2FDeviceBuilder.cpp;h=81b4e2a50014564c4acfd8e00d59f26a593dc6a9;hb=d07c171fa694cae985ad7045f9ce2b2f1a5699b4;hp=0000000000000000000000000000000000000000;hpb=ca22e7b76883b946060a6b40bb8709c1981e1cf6;p=mupen64plus-pandora.git diff --git a/source/rice_gles/src/DeviceBuilder.cpp b/source/rice_gles/src/DeviceBuilder.cpp new file mode 100755 index 0000000..81b4e2a --- /dev/null +++ b/source/rice_gles/src/DeviceBuilder.cpp @@ -0,0 +1,383 @@ +/* +Copyright (C) 2003 Rice1964 + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "osal_opengl.h" + +#include "DeviceBuilder.h" +#include "FrameBuffer.h" +#include "OGLCombiner.h" +#include "OGLDebug.h" +#include "OGLExtRender.h" +#include "OGLGraphicsContext.h" +#include "OGLTexture.h" +#if SDL_VIDEO_OPENGL +#include "OGLExtCombiner.h" +#ifndef HAVE_GLES +#include "OGLCombinerNV.h" +#include "OGLCombinerTNT2.h" +#include "OGLFragmentShaders.h" +#endif +#include "OGLExtensions.h" +#elif SDL_VIDEO_OPENGL_ES2 +#include "OGLES2FragmentShaders.h" +#endif + +//======================================================================== +CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL; +SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE; +SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE; + +CDeviceBuilder* CDeviceBuilder::GetBuilder(void) +{ + if( m_pInstance == NULL ) + CreateBuilder(m_deviceType); + + return m_pInstance; +} + +void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type) +{ + if( type != m_deviceType && m_pInstance != NULL ) + { + DeleteBuilder(); + } + + CDeviceBuilder::m_deviceType = type; + switch(type) + { + case OGL_DEVICE: + case OGL_1_1_DEVICE: + case OGL_1_2_DEVICE: + case OGL_1_3_DEVICE: + case OGL_1_4_DEVICE: + case OGL_1_4_V2_DEVICE: + case OGL_TNT2_DEVICE: + case NVIDIA_OGL_DEVICE: + case OGL_FRAGMENT_PROGRAM: + CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE; + break; + default: + break; + } +} + +SupportedDeviceType CDeviceBuilder::GetDeviceType(void) +{ + return CDeviceBuilder::m_deviceType; +} + +SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void) +{ + return CDeviceBuilder::m_deviceGeneralType; +} + +CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type) +{ + if( m_pInstance == NULL ) + { + switch( type ) + { + case OGL_DEVICE: + case OGL_1_1_DEVICE: + case OGL_1_2_DEVICE: + case OGL_1_3_DEVICE: + case OGL_1_4_DEVICE: + case OGL_1_4_V2_DEVICE: + case OGL_TNT2_DEVICE: + case NVIDIA_OGL_DEVICE: + case OGL_FRAGMENT_PROGRAM: + m_pInstance = new OGLDeviceBuilder(); + break; + default: + DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type"); + exit(1); + } + + SAFE_CHECK(m_pInstance); + } + + return m_pInstance; +} + +void CDeviceBuilder::DeleteBuilder(void) +{ + delete m_pInstance; + m_pInstance = NULL; +} + +CDeviceBuilder::CDeviceBuilder() : + m_pRender(NULL), + m_pGraphicsContext(NULL), + m_pColorCombiner(NULL), + m_pAlphaBlender(NULL) +{ +} + +CDeviceBuilder::~CDeviceBuilder() +{ + DeleteGraphicsContext(); + DeleteRender(); + DeleteColorCombiner(); + DeleteAlphaBlender(); +} + +void CDeviceBuilder::DeleteGraphicsContext(void) +{ + if( m_pGraphicsContext != NULL ) + { + delete m_pGraphicsContext; + CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL; + } + + SAFE_DELETE(g_pFrameBufferManager); +} + +void CDeviceBuilder::DeleteRender(void) +{ + if( m_pRender != NULL ) + { + delete m_pRender; + CRender::g_pRender = m_pRender = NULL; + CRender::gRenderReferenceCount = 0; + } +} + +void CDeviceBuilder::DeleteColorCombiner(void) +{ + if( m_pColorCombiner != NULL ) + { + delete m_pColorCombiner; + m_pColorCombiner = NULL; + } +} + +void CDeviceBuilder::DeleteAlphaBlender(void) +{ + if( m_pAlphaBlender != NULL ) + { + delete m_pAlphaBlender; + m_pAlphaBlender = NULL; + } +} + + +//======================================================================== + +CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void) +{ + if( m_pGraphicsContext == NULL ) + { + m_pGraphicsContext = new COGLGraphicsContext(); + SAFE_CHECK(m_pGraphicsContext); + CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext; + } + + g_pFrameBufferManager = new FrameBufferManager; + return m_pGraphicsContext; +} + +CRender * OGLDeviceBuilder::CreateRender(void) +{ + if( m_pRender == NULL ) + { + if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() ) + { + DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext"); + m_pRender = NULL; + SAFE_CHECK(m_pRender); + } + + COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext); + + if( context.m_bSupportMultiTexture ) + { + // OGL extension render + m_pRender = new COGLExtRender(); + } + else + { + // Basic OGL Render + m_pRender = new OGLRender(); + } + SAFE_CHECK(m_pRender); + CRender::g_pRender = m_pRender; + } + + return m_pRender; +} + +CTexture * OGLDeviceBuilder::CreateTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) +{ + COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage); + if( txtr->m_pTexture == NULL ) + { + delete txtr; + TRACE0("Cannot create new texture, out of video memory"); + return NULL; + } + else + return txtr; +} + +CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender) +{ + if( m_pColorCombiner == NULL ) + { + if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() ) + { + DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext"); + } + else + { + m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting; + +#if SDL_VIDEO_OPENGL + + if (m_deviceType == NVIDIA_OGL_DEVICE && !bNvidiaExtensionsSupported) + { + DebugMessage(M64MSG_WARNING, "Your video card does not support Nvidia OpenGL extensions. Falling back to auto device."); + m_deviceType = OGL_DEVICE; + } + if( m_deviceType == OGL_DEVICE ) // Best fit + { + GLint maxUnit = 2; + COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext); + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&maxUnit); + OPENGL_CHECK_ERRORS; +#ifndef HAVE_GLES + if( pcontext->IsExtensionSupported("GL_ARB_fragment_program") ) + { + m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program"); + } + else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") || + pcontext->IsExtensionSupported("GL_NV_register_combiners") ) + { + m_pColorCombiner = new COGLColorCombinerNvidia(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: NVidia"); + } + else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") ) + { + m_pColorCombiner = new COGLColorCombinerTNT2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2"); + } + else if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") || + pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") ) + { + if( pcontext->IsExtensionSupported("GL_ARB_texture_env_crossbar") ) +#endif + { +#ifndef HAVE_GLES + if( maxUnit > 2 ) + { + m_pColorCombiner = new COGLColorCombiner4v2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2"); + } + else +#endif + { + m_pColorCombiner = new COGLColorCombiner4(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4"); + } + } +#ifndef HAVE_GLES + else + { + if( maxUnit > 2 ) + { + m_pColorCombiner = new COGLColorCombiner4v2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2 (w/o env crossbar)"); + } + else + { + m_pColorCombiner = new COGLColorCombiner2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3"); + } + } + } + else + { + m_pColorCombiner = new COGLColorCombiner(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL"); + } +#endif + } + else + { + switch(m_deviceType) + { + case OGL_1_1_DEVICE: + m_pColorCombiner = new COGLColorCombiner(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL"); + break; + case OGL_1_2_DEVICE: + case OGL_1_3_DEVICE: + m_pColorCombiner = new COGLColorCombiner2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3"); + break; + case OGL_1_4_DEVICE: + m_pColorCombiner = new COGLColorCombiner4(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4"); + break; + case OGL_1_4_V2_DEVICE: + m_pColorCombiner = new COGLColorCombiner4v2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 Version 2"); + break; +#ifndef HAVE_GLES + case OGL_TNT2_DEVICE: + m_pColorCombiner = new COGLColorCombinerTNT2(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2"); + break; + case NVIDIA_OGL_DEVICE: + m_pColorCombiner = new COGLColorCombinerNvidia(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Nvidia"); + break; + case OGL_FRAGMENT_PROGRAM: + m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program"); + break; +#endif + default: + break; + } + } + +#elif SDL_VIDEO_OPENGL_ES2 + m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender); + DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program"); +#endif + } + + SAFE_CHECK(m_pColorCombiner); + } + + return m_pColorCombiner; +} + +CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender) +{ + if( m_pAlphaBlender == NULL ) + { + m_pAlphaBlender = new COGLBlender(pRender); + SAFE_CHECK(m_pAlphaBlender); + } + + return m_pAlphaBlender; +} +