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 "OGLCombinerNV.h"
31 #include "OGLCombinerTNT2.h"
32 #include "OGLExtensions.h"
33 #include "OGLFragmentShaders.h"
34 #elif SDL_VIDEO_OPENGL_ES2
35 #include "OGLES2FragmentShaders.h"
38 //========================================================================
39 CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL;
40 SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE;
41 SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE;
43 CDeviceBuilder* CDeviceBuilder::GetBuilder(void)
45 if( m_pInstance == NULL )
46 CreateBuilder(m_deviceType);
51 void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type)
53 if( type != m_deviceType && m_pInstance != NULL )
58 CDeviceBuilder::m_deviceType = type;
66 case OGL_1_4_V2_DEVICE:
68 case NVIDIA_OGL_DEVICE:
69 case OGL_FRAGMENT_PROGRAM:
70 CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE;
77 SupportedDeviceType CDeviceBuilder::GetDeviceType(void)
79 return CDeviceBuilder::m_deviceType;
82 SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void)
84 return CDeviceBuilder::m_deviceGeneralType;
87 CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type)
89 if( m_pInstance == NULL )
98 case OGL_1_4_V2_DEVICE:
100 case NVIDIA_OGL_DEVICE:
101 case OGL_FRAGMENT_PROGRAM:
102 m_pInstance = new OGLDeviceBuilder();
105 DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type");
109 SAFE_CHECK(m_pInstance);
115 void CDeviceBuilder::DeleteBuilder(void)
121 CDeviceBuilder::CDeviceBuilder() :
123 m_pGraphicsContext(NULL),
124 m_pColorCombiner(NULL),
125 m_pAlphaBlender(NULL)
129 CDeviceBuilder::~CDeviceBuilder()
131 DeleteGraphicsContext();
133 DeleteColorCombiner();
134 DeleteAlphaBlender();
137 void CDeviceBuilder::DeleteGraphicsContext(void)
139 if( m_pGraphicsContext != NULL )
141 delete m_pGraphicsContext;
142 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL;
145 SAFE_DELETE(g_pFrameBufferManager);
148 void CDeviceBuilder::DeleteRender(void)
150 if( m_pRender != NULL )
153 CRender::g_pRender = m_pRender = NULL;
154 CRender::gRenderReferenceCount = 0;
158 void CDeviceBuilder::DeleteColorCombiner(void)
160 if( m_pColorCombiner != NULL )
162 delete m_pColorCombiner;
163 m_pColorCombiner = NULL;
167 void CDeviceBuilder::DeleteAlphaBlender(void)
169 if( m_pAlphaBlender != NULL )
171 delete m_pAlphaBlender;
172 m_pAlphaBlender = NULL;
177 //========================================================================
179 CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void)
181 if( m_pGraphicsContext == NULL )
183 m_pGraphicsContext = new COGLGraphicsContext();
184 SAFE_CHECK(m_pGraphicsContext);
185 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext;
188 g_pFrameBufferManager = new FrameBufferManager;
189 return m_pGraphicsContext;
192 CRender * OGLDeviceBuilder::CreateRender(void)
194 if( m_pRender == NULL )
196 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
198 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
200 SAFE_CHECK(m_pRender);
203 COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext);
205 if( context.m_bSupportMultiTexture )
207 // OGL extension render
208 m_pRender = new COGLExtRender();
213 m_pRender = new OGLRender();
215 SAFE_CHECK(m_pRender);
216 CRender::g_pRender = m_pRender;
222 CTexture * OGLDeviceBuilder::CreateTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage)
224 COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage);
225 if( txtr->m_pTexture == NULL )
228 TRACE0("Cannot create new texture, out of video memory");
235 CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender)
237 if( m_pColorCombiner == NULL )
239 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
241 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
245 m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting;
249 if (m_deviceType == NVIDIA_OGL_DEVICE && !bNvidiaExtensionsSupported)
251 DebugMessage(M64MSG_WARNING, "Your video card does not support Nvidia OpenGL extensions. Falling back to auto device.");
252 m_deviceType = OGL_DEVICE;
254 if( m_deviceType == OGL_DEVICE ) // Best fit
257 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
258 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&maxUnit);
261 if( pcontext->IsExtensionSupported("GL_ARB_fragment_program") )
263 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
264 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
266 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") ||
267 pcontext->IsExtensionSupported("GL_NV_register_combiners") )
269 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
270 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: NVidia");
272 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") )
274 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
275 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
277 else if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") ||
278 pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
280 if( pcontext->IsExtensionSupported("GL_ARB_texture_env_crossbar") )
284 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
285 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2");
289 m_pColorCombiner = new COGLColorCombiner4(pRender);
290 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
297 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
298 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2 (w/o env crossbar)");
302 m_pColorCombiner = new COGLColorCombiner2(pRender);
303 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
309 m_pColorCombiner = new COGLColorCombiner(pRender);
310 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
318 m_pColorCombiner = new COGLColorCombiner(pRender);
319 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
323 m_pColorCombiner = new COGLColorCombiner2(pRender);
324 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
327 m_pColorCombiner = new COGLColorCombiner4(pRender);
328 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
330 case OGL_1_4_V2_DEVICE:
331 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
332 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 Version 2");
334 case OGL_TNT2_DEVICE:
335 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
336 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
338 case NVIDIA_OGL_DEVICE:
339 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
340 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Nvidia");
342 case OGL_FRAGMENT_PROGRAM:
343 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
344 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
351 #elif SDL_VIDEO_OPENGL_ES2
352 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
353 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
357 SAFE_CHECK(m_pColorCombiner);
360 return m_pColorCombiner;
363 CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender)
365 if( m_pAlphaBlender == NULL )
367 m_pAlphaBlender = new COGLBlender(pRender);
368 SAFE_CHECK(m_pAlphaBlender);
371 return m_pAlphaBlender;