Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / DeviceBuilder.cpp
CommitLineData
292f9317 1/*
2Copyright (C) 2003 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18*/
19
20#include "osal_opengl.h"
21
22#include "DeviceBuilder.h"
23#include "FrameBuffer.h"
24#include "OGLCombiner.h"
25#include "OGLDebug.h"
26#include "OGLExtRender.h"
27#include "OGLGraphicsContext.h"
28#include "OGLTexture.h"
29#if SDL_VIDEO_OPENGL
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"
36#endif
37
38//========================================================================
39CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL;
40SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE;
41SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE;
42
43CDeviceBuilder* CDeviceBuilder::GetBuilder(void)
44{
45 if( m_pInstance == NULL )
46 CreateBuilder(m_deviceType);
47
48 return m_pInstance;
49}
50
51void CDeviceBuilder::SelectDeviceType(SupportedDeviceType type)
52{
53 if( type != m_deviceType && m_pInstance != NULL )
54 {
55 DeleteBuilder();
56 }
57
58 CDeviceBuilder::m_deviceType = type;
59 switch(type)
60 {
61 case OGL_DEVICE:
62 case OGL_1_1_DEVICE:
63 case OGL_1_2_DEVICE:
64 case OGL_1_3_DEVICE:
65 case OGL_1_4_DEVICE:
66 case OGL_1_4_V2_DEVICE:
67 case OGL_TNT2_DEVICE:
68 case NVIDIA_OGL_DEVICE:
69 case OGL_FRAGMENT_PROGRAM:
70 CDeviceBuilder::m_deviceGeneralType = OGL_DEVICE;
71 break;
72 default:
73 break;
74 }
75}
76
77SupportedDeviceType CDeviceBuilder::GetDeviceType(void)
78{
79 return CDeviceBuilder::m_deviceType;
80}
81
82SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void)
83{
84 return CDeviceBuilder::m_deviceGeneralType;
85}
86
87CDeviceBuilder* CDeviceBuilder::CreateBuilder(SupportedDeviceType type)
88{
89 if( m_pInstance == NULL )
90 {
91 switch( type )
92 {
93 case OGL_DEVICE:
94 case OGL_1_1_DEVICE:
95 case OGL_1_2_DEVICE:
96 case OGL_1_3_DEVICE:
97 case OGL_1_4_DEVICE:
98 case OGL_1_4_V2_DEVICE:
99 case OGL_TNT2_DEVICE:
100 case NVIDIA_OGL_DEVICE:
101 case OGL_FRAGMENT_PROGRAM:
102 m_pInstance = new OGLDeviceBuilder();
103 break;
104 default:
105 DebugMessage(M64MSG_ERROR, "CreateBuilder: unknown OGL device type");
106 exit(1);
107 }
108
109 SAFE_CHECK(m_pInstance);
110 }
111
112 return m_pInstance;
113}
114
115void CDeviceBuilder::DeleteBuilder(void)
116{
117 delete m_pInstance;
118 m_pInstance = NULL;
119}
120
121CDeviceBuilder::CDeviceBuilder() :
122 m_pRender(NULL),
123 m_pGraphicsContext(NULL),
124 m_pColorCombiner(NULL),
125 m_pAlphaBlender(NULL)
126{
127}
128
129CDeviceBuilder::~CDeviceBuilder()
130{
131 DeleteGraphicsContext();
132 DeleteRender();
133 DeleteColorCombiner();
134 DeleteAlphaBlender();
135}
136
137void CDeviceBuilder::DeleteGraphicsContext(void)
138{
139 if( m_pGraphicsContext != NULL )
140 {
141 delete m_pGraphicsContext;
142 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext = NULL;
143 }
144
145 SAFE_DELETE(g_pFrameBufferManager);
146}
147
148void CDeviceBuilder::DeleteRender(void)
149{
150 if( m_pRender != NULL )
151 {
152 delete m_pRender;
153 CRender::g_pRender = m_pRender = NULL;
154 CRender::gRenderReferenceCount = 0;
155 }
156}
157
158void CDeviceBuilder::DeleteColorCombiner(void)
159{
160 if( m_pColorCombiner != NULL )
161 {
162 delete m_pColorCombiner;
163 m_pColorCombiner = NULL;
164 }
165}
166
167void CDeviceBuilder::DeleteAlphaBlender(void)
168{
169 if( m_pAlphaBlender != NULL )
170 {
171 delete m_pAlphaBlender;
172 m_pAlphaBlender = NULL;
173 }
174}
175
176
177//========================================================================
178
179CGraphicsContext * OGLDeviceBuilder::CreateGraphicsContext(void)
180{
181 if( m_pGraphicsContext == NULL )
182 {
183 m_pGraphicsContext = new COGLGraphicsContext();
184 SAFE_CHECK(m_pGraphicsContext);
185 CGraphicsContext::g_pGraphicsContext = m_pGraphicsContext;
186 }
187
188 g_pFrameBufferManager = new FrameBufferManager;
189 return m_pGraphicsContext;
190}
191
192CRender * OGLDeviceBuilder::CreateRender(void)
193{
194 if( m_pRender == NULL )
195 {
196 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
197 {
198 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
199 m_pRender = NULL;
200 SAFE_CHECK(m_pRender);
201 }
202
203 COGLGraphicsContext &context = *((COGLGraphicsContext*)CGraphicsContext::g_pGraphicsContext);
204
205 if( context.m_bSupportMultiTexture )
206 {
207 // OGL extension render
208 m_pRender = new COGLExtRender();
209 }
210 else
211 {
212 // Basic OGL Render
213 m_pRender = new OGLRender();
214 }
215 SAFE_CHECK(m_pRender);
216 CRender::g_pRender = m_pRender;
217 }
218
219 return m_pRender;
220}
221
222CTexture * OGLDeviceBuilder::CreateTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage)
223{
224 COGLTexture *txtr = new COGLTexture(dwWidth, dwHeight, usage);
225 if( txtr->m_pTexture == NULL )
226 {
227 delete txtr;
228 TRACE0("Cannot create new texture, out of video memory");
229 return NULL;
230 }
231 else
232 return txtr;
233}
234
235CColorCombiner * OGLDeviceBuilder::CreateColorCombiner(CRender *pRender)
236{
237 if( m_pColorCombiner == NULL )
238 {
239 if( CGraphicsContext::g_pGraphicsContext == NULL && CGraphicsContext::g_pGraphicsContext->Ready() )
240 {
241 DebugMessage(M64MSG_ERROR, "Can not create ColorCombiner before creating and initializing GraphicsContext");
242 }
243 else
244 {
245 m_deviceType = (SupportedDeviceType)options.OpenglRenderSetting;
246
247#if SDL_VIDEO_OPENGL
248
249 if (m_deviceType == NVIDIA_OGL_DEVICE && !bNvidiaExtensionsSupported)
250 {
251 DebugMessage(M64MSG_WARNING, "Your video card does not support Nvidia OpenGL extensions. Falling back to auto device.");
252 m_deviceType = OGL_DEVICE;
253 }
254 if( m_deviceType == OGL_DEVICE ) // Best fit
255 {
256 GLint maxUnit = 2;
257 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
258 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&maxUnit);
259 OPENGL_CHECK_ERRORS;
260
261 if( pcontext->IsExtensionSupported("GL_ARB_fragment_program") )
262 {
263 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
264 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
265 }
266 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") ||
267 pcontext->IsExtensionSupported("GL_NV_register_combiners") )
268 {
269 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
270 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: NVidia");
271 }
272 else if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") )
273 {
274 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
275 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
276 }
277 else if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") ||
278 pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") )
279 {
280 if( pcontext->IsExtensionSupported("GL_ARB_texture_env_crossbar") )
281 {
282 if( maxUnit > 2 )
283 {
284 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
285 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2");
286 }
287 else
288 {
289 m_pColorCombiner = new COGLColorCombiner4(pRender);
290 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
291 }
292 }
293 else
294 {
295 if( maxUnit > 2 )
296 {
297 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
298 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 version 2 (w/o env crossbar)");
299 }
300 else
301 {
302 m_pColorCombiner = new COGLColorCombiner2(pRender);
303 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
304 }
305 }
306 }
307 else
308 {
309 m_pColorCombiner = new COGLColorCombiner(pRender);
310 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
311 }
312 }
313 else
314 {
315 switch(m_deviceType)
316 {
317 case OGL_1_1_DEVICE:
318 m_pColorCombiner = new COGLColorCombiner(pRender);
319 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Basic OGL");
320 break;
321 case OGL_1_2_DEVICE:
322 case OGL_1_3_DEVICE:
323 m_pColorCombiner = new COGLColorCombiner2(pRender);
324 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.2/1.3");
325 break;
326 case OGL_1_4_DEVICE:
327 m_pColorCombiner = new COGLColorCombiner4(pRender);
328 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4");
329 break;
330 case OGL_1_4_V2_DEVICE:
331 m_pColorCombiner = new COGLColorCombiner4v2(pRender);
332 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: OGL 1.4 Version 2");
333 break;
334 case OGL_TNT2_DEVICE:
335 m_pColorCombiner = new COGLColorCombinerTNT2(pRender);
336 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: TNT2");
337 break;
338 case NVIDIA_OGL_DEVICE:
339 m_pColorCombiner = new COGLColorCombinerNvidia(pRender);
340 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Nvidia");
341 break;
342 case OGL_FRAGMENT_PROGRAM:
343 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
344 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
345 break;
346 default:
347 break;
348 }
349 }
350
351#elif SDL_VIDEO_OPENGL_ES2
352 m_pColorCombiner = new COGL_FragmentProgramCombiner(pRender);
353 DebugMessage(M64MSG_VERBOSE, "OpenGL Combiner: Fragment Program");
354#endif
355 }
356
357 SAFE_CHECK(m_pColorCombiner);
358 }
359
360 return m_pColorCombiner;
361}
362
363CBlender * OGLDeviceBuilder::CreateAlphaBlender(CRender *pRender)
364{
365 if( m_pAlphaBlender == NULL )
366 {
367 m_pAlphaBlender = new COGLBlender(pRender);
368 SAFE_CHECK(m_pAlphaBlender);
369 }
370
371 return m_pAlphaBlender;
372}
373