2 Copyright (C) 2003 Rice1964
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "osal_opengl.h"
22 #include "DeviceBuilder.h"
23 #include "FrameBuffer.h"
24 #include "OGLCombiner.h"
26 #include "OGLExtRender.h"
27 #include "OGLGraphicsContext.h"
28 #include "OGLTexture.h"
30 #include "OGLExtCombiner.h"
32 #include "OGLCombinerNV.h"
33 #include "OGLCombinerTNT2.h"
34 #include "OGLFragmentShaders.h"
36 #include "OGLExtensions.h"
37 #elif SDL_VIDEO_OPENGL_ES2
38 #include "OGLES2FragmentShaders.h"
41 //========================================================================
42 CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL;
43 SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE;
44 SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE;
46 CDeviceBuilder* CDeviceBuilder::GetBuilder(void)
48 if( m_pInstance == NULL )
49 CreateBuilder(m_deviceType);
54 void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type)
56 if( type != m_deviceType && m_pInstance != NULL )
61 CDeviceBuilder::m_deviceType = type;
69 case OGL_1_4_V2_DEVICE:
71 case NVIDIA_OGL_DEVICE:
72 case OGL_FRAGMENT_PROGRAM:
73 CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE;
80 SupportedDeviceType CDeviceBuilder::GetDeviceType(void)
82 return CDeviceBuilder::m_deviceType;
85 SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void)
87 return CDeviceBuilder::m_deviceGeneralType;
90 CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type)
92 if( m_pInstance == NULL )
101 case OGL_1_4_V2_DEVICE:
102 case OGL_TNT2_DEVICE:
103 case NVIDIA_OGL_DEVICE:
104 case OGL_FRAGMENT_PROGRAM:
105 m_pInstance = new OGLDeviceBuilder();
108 DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type");
112 SAFE_CHECK(m_pInstance);
118 void CDeviceBuilder::DeleteBuilder(void)
124 CDeviceBuilder::CDeviceBuilder() :
126 m_pGraphicsContext(NULL),
127 m_pColorCombiner(NULL),
128 m_pAlphaBlender(NULL)
132 CDeviceBuilder::~CDeviceBuilder()
134 DeleteGraphicsContext();
136 DeleteColorCombiner();
137 DeleteAlphaBlender();
140 void CDeviceBuilder::DeleteGraphicsContext(void)
142 if( m_pGraphicsContext != NULL )
144 delete m_pGraphicsContext;
145 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL;
148 SAFE_DELETE(g_pFrameBufferManager);
151 void CDeviceBuilder::DeleteRender(void)
153 if( m_pRender != NULL )
156 CRender::g_pRender = m_pRender = NULL;
157 CRender::gRenderReferenceCount = 0;
161 void CDeviceBuilder::DeleteColorCombiner(void)
163 if( m_pColorCombiner != NULL )
165 delete m_pColorCombiner;
166 m_pColorCombiner = NULL;
170 void CDeviceBuilder::DeleteAlphaBlender(void)
172 if( m_pAlphaBlender != NULL )
174 delete m_pAlphaBlender;
175 m_pAlphaBlender = NULL;
180 //========================================================================
182 CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void)
184 if( m_pGraphicsContext == NULL )
186 m_pGraphicsContext = new COGLGraphicsContext();
187 SAFE_CHECK(m_pGraphicsContext);
188 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext;
191 g_pFrameBufferManager = new FrameBufferManager;
192 return m_pGraphicsContext;
195 CRender * OGLDeviceBuilder::CreateRender(void)
197 if( m_pRender == NULL )
199 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
201 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
203 SAFE_CHECK(m_pRender);
206 COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext);
208 if( context.m_bSupportMultiTexture )
210 // OGL extension render
211 m_pRender = new COGLExtRender();
216 m_pRender = new OGLRender();
218 SAFE_CHECK(m_pRender);
219 CRender::g_pRender = m_pRender;
225 CTexture * OGLDeviceBuilder::CreateTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage)
227 COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage);
228 if( txtr->m_pTexture == NULL )
231 TRACE0("Cannot create new texture, out of video memory");
238 CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender)
240 if( m_pColorCombiner == NULL )
242 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
244 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
248 m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting;
252 if (m_deviceType == NVIDIA_OGL_DEVICE && !bNvidiaExtensionsSupported)
254 DebugMessage(M64MSG_WARNING, "Your video card does not support Nvidia OpenGL extensions. Falling back to auto device.");
255 m_deviceType = OGL_DEVICE;
257 if( m_deviceType == OGL_DEVICE ) // Best fit
260 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
261 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&maxUnit);
264 if( pcontext->IsExtensionSupported("GL_ARB_fragment_program") )
266 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
267 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
269 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") ||
270 pcontext->IsExtensionSupported("GL_NV_register_combiners") )
272 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
273 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: NVidia");
275 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") )
277 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
278 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
280 else if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") ||
281 pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
283 if( pcontext->IsExtensionSupported("GL_ARB_texture_env_crossbar") )
289 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
290 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2");
295 m_pColorCombiner = new COGLColorCombiner4(pRender);
296 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
304 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
305 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2 (w/o env crossbar)");
309 m_pColorCombiner = new COGLColorCombiner2(pRender);
310 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
316 m_pColorCombiner = new COGLColorCombiner(pRender);
317 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
326 m_pColorCombiner = new COGLColorCombiner(pRender);
327 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
331 m_pColorCombiner = new COGLColorCombiner2(pRender);
332 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
335 m_pColorCombiner = new COGLColorCombiner4(pRender);
336 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
338 case OGL_1_4_V2_DEVICE:
339 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
340 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 Version 2");
343 case OGL_TNT2_DEVICE:
344 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
345 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
347 case NVIDIA_OGL_DEVICE:
348 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
349 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Nvidia");
351 case OGL_FRAGMENT_PROGRAM:
352 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
353 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
361 #elif SDL_VIDEO_OPENGL_ES2
362 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
363 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
367 SAFE_CHECK(m_pColorCombiner);
370 return m_pColorCombiner;
373 CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender)
375 if( m_pAlphaBlender == NULL )
377 m_pAlphaBlender = new COGLBlender(pRender);
378 SAFE_CHECK(m_pAlphaBlender);
381 return m_pAlphaBlender;