Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/DeviceBuilder.cpp
2 views
1
/*
2
Copyright (C) 2003 Rice1964
3
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.
8
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.
13
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.
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
//========================================================================
39
CDeviceBuilder* CDeviceBuilder::m_pInstance=NULL;
40
SupportedDeviceType CDeviceBuilder::m_deviceType = DIRECTX_DEVICE;
41
SupportedDeviceType CDeviceBuilder::m_deviceGeneralType = DIRECTX_DEVICE;
42
43
CDeviceBuilder* CDeviceBuilder::GetBuilder(void)
44
{
45
if( m_pInstance == NULL )
46
CreateBuilder(m_deviceType);
47
48
return m_pInstance;
49
}
50
51
void 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
77
SupportedDeviceType CDeviceBuilder::GetDeviceType(void)
78
{
79
return CDeviceBuilder::m_deviceType;
80
}
81
82
SupportedDeviceType CDeviceBuilder::GetGeneralDeviceType(void)
83
{
84
return CDeviceBuilder::m_deviceGeneralType;
85
}
86
87
CDeviceBuilder* 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
115
void CDeviceBuilder::DeleteBuilder(void)
116
{
117
delete m_pInstance;
118
m_pInstance = NULL;
119
}
120
121
CDeviceBuilder::CDeviceBuilder() :
122
m_pRender(NULL),
123
m_pGraphicsContext(NULL),
124
m_pColorCombiner(NULL),
125
m_pAlphaBlender(NULL)
126
{
127
}
128
129
CDeviceBuilder::~CDeviceBuilder()
130
{
131
DeleteGraphicsContext();
132
DeleteRender();
133
DeleteColorCombiner();
134
DeleteAlphaBlender();
135
}
136
137
void 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
148
void 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
158
void CDeviceBuilder::DeleteColorCombiner(void)
159
{
160
if( m_pColorCombiner != NULL )
161
{
162
delete m_pColorCombiner;
163
m_pColorCombiner = NULL;
164
}
165
}
166
167
void CDeviceBuilder::DeleteAlphaBlender(void)
168
{
169
if( m_pAlphaBlender != NULL )
170
{
171
delete m_pAlphaBlender;
172
m_pAlphaBlender = NULL;
173
}
174
}
175
176
177
//========================================================================
178
179
CGraphicsContext * 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
192
CRender * 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
222
CTexture * 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
235
CColorCombiner * 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
363
CBlender * 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
374
375