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.
19
#include <SDL_opengl.h>
23
#include "liblinux/BMGLibPNG.h"
25
#include "../main/version.h"
27
COGLGraphicsContext::COGLGraphicsContext() :
29
m_bSupportMultiTexture(false),
30
m_bSupportTextureEnvCombine(false),
31
m_bSupportSeparateSpecularColor(false),
32
m_bSupportSecondColor(false),
33
m_bSupportFogCoord(false),
34
m_bSupportTextureObject(false),
35
m_bSupportRescaleNormal(false),
36
m_bSupportLODBias(false),
37
m_bSupportTextureMirrorRepeat(false),
38
m_bSupportTextureLOD(false),
39
m_bSupportNVRegisterCombiner(false),
40
m_bSupportBlendColor(false),
41
m_bSupportBlendSubtract(false),
42
m_bSupportNVTextureEnvCombine4(false),
45
m_pExtensionStr(NULL),
51
COGLGraphicsContext::~COGLGraphicsContext()
55
bool COGLGraphicsContext::Initialize(HWND hWnd, HWND hWndStatus, uint32 dwWidth, uint32 dwHeight, BOOL bWindowed )
57
printf("Initializing OpenGL Device Context\n");
60
CGraphicsContext::Get()->m_supportTextureMirror = false;
61
CGraphicsContext::Initialize(hWnd, hWndStatus, dwWidth, dwHeight, bWindowed );
65
windowSetting.statusBarHeightToUse = windowSetting.statusBarHeight;
66
windowSetting.toolbarHeightToUse = windowSetting.toolbarHeight;
70
windowSetting.statusBarHeightToUse = 0;
71
windowSetting.toolbarHeightToUse = 0;
74
int depthBufferDepth = options.OpenglDepthBufferSetting;
75
int colorBufferDepth = 32;
76
if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) colorBufferDepth = 16;
79
const SDL_VideoInfo *videoInfo;
80
Uint32 videoFlags = 0;
83
printf("(II) Initializing SDL video subsystem...\n");
84
if(SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
86
printf("(EE) Error initializing SDL video subsystem: %s\n", SDL_GetError());
91
printf("(II) Getting video info...\n");
92
if(!(videoInfo = SDL_GetVideoInfo()))
94
printf("(EE) Video query failed: %s\n", SDL_GetError());
95
SDL_QuitSubSystem(SDL_INIT_VIDEO);
98
/* Setting the video mode */
99
videoFlags |= SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE;
101
if(videoInfo->hw_available)
102
videoFlags |= SDL_HWSURFACE;
104
videoFlags |= SDL_SWSURFACE;
106
if(videoInfo->blit_hw)
107
videoFlags |= SDL_HWACCEL;
110
videoFlags |= SDL_FULLSCREEN;
112
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
113
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, colorBufferDepth);
114
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBufferDepth);
116
printf("(II) Setting video mode %dx%d...\n", (int)windowSetting.uDisplayWidth, (int)windowSetting.uDisplayHeight);
117
if(!(m_pScreen = SDL_SetVideoMode(windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, colorBufferDepth, videoFlags)))
119
printf("(EE) Error setting video mode %dx%d: %s\n", (int)windowSetting.uDisplayWidth, (int)windowSetting.uDisplayHeight, SDL_GetError());
120
SDL_QuitSubSystem(SDL_INIT_VIDEO);
125
sprintf(caption, "RiceVideoLinux N64 Plugin %s", MUPEN_VERSION);
126
SDL_WM_SetCaption(caption, caption);
131
sprintf(m_strDeviceStats, "%.60s - %.128s : %.60s", m_pVendorStr, m_pRenderStr, m_pVersionStr);
132
TRACE0(m_strDeviceStats);
133
printf("%s\n", m_strDeviceStats);
137
Clear(CLEAR_COLOR_AND_DEPTH_BUFFER); // Clear buffers
139
Clear(CLEAR_COLOR_AND_DEPTH_BUFFER);
143
status.isVertexShaderEnabled = false;
148
void COGLGraphicsContext::InitState(void)
150
m_pRenderStr = glGetString(GL_RENDERER);;
151
m_pExtensionStr = glGetString(GL_EXTENSIONS);;
152
m_pVersionStr = glGetString(GL_VERSION);;
153
m_pVendorStr = glGetString(GL_VENDOR);
154
glMatrixMode(GL_PROJECTION);
157
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
160
glShadeModel(GL_SMOOTH);
163
//glMatrixMode(GL_MODELVIEW);
166
glDisable(GL_ALPHA_TEST);
168
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
172
glDisable(GL_CULL_FACE);
173
glDisable(GL_NORMALIZE);
175
glDepthFunc(GL_LEQUAL);
176
glEnable(GL_DEPTH_TEST);
178
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
181
glEnable(GL_ALPHA_TEST);
183
glMatrixMode(GL_PROJECTION);
189
void COGLGraphicsContext::InitOGLExtension(void)
191
// important extension features, it is very bad not to have these feature
192
m_bSupportMultiTexture = IsExtensionSupported("GL_ARB_multitexture");
193
m_bSupportTextureEnvCombine = IsExtensionSupported("GL_EXT_texture_env_combine");
195
m_bSupportSeparateSpecularColor = IsExtensionSupported("GL_EXT_separate_specular_color");
196
m_bSupportSecondColor = IsExtensionSupported("GL_EXT_secondary_color");
197
m_bSupportFogCoord = IsExtensionSupported("GL_EXT_fog_coord");
198
m_bSupportTextureObject = IsExtensionSupported("GL_EXT_texture_object");
200
// Optional extension features
201
m_bSupportRescaleNormal = IsExtensionSupported("GL_EXT_rescale_normal");
202
m_bSupportLODBias = IsExtensionSupported("GL_EXT_texture_lod_bias");
204
// Nvidia only extension features (optional)
205
m_bSupportNVRegisterCombiner = IsExtensionSupported("GL_NV_register_combiners");
206
m_bSupportTextureMirrorRepeat = IsExtensionSupported("GL_IBM_texture_mirrored_repeat") || IsExtensionSupported("ARB_texture_mirrored_repeat");
207
m_supportTextureMirror = m_bSupportTextureMirrorRepeat;
208
m_bSupportTextureLOD = IsExtensionSupported("GL_EXT_texture_lod");
209
m_bSupportBlendColor = IsExtensionSupported("GL_EXT_blend_color");
210
m_bSupportBlendSubtract = IsExtensionSupported("GL_EXT_blend_subtract");
211
m_bSupportNVTextureEnvCombine4 = IsExtensionSupported("GL_NV_texture_env_combine4");
215
bool COGLGraphicsContext::IsExtensionSupported(const char* pExtName)
217
if( strstr((const char*)m_pExtensionStr, pExtName) != NULL )
223
bool COGLGraphicsContext::IsWglExtensionSupported(const char* pExtName)
225
if( m_pWglExtensionStr == NULL )
228
if( strstr((const char*)m_pWglExtensionStr, pExtName) != NULL )
235
void COGLGraphicsContext::CleanUp()
237
SDL_QuitSubSystem(SDL_INIT_VIDEO);
243
void COGLGraphicsContext::Clear(ClearFlag dwFlags, uint32 color, float depth)
246
if( dwFlags&CLEAR_COLOR_BUFFER ) flag |= GL_COLOR_BUFFER_BIT;
247
if( dwFlags&CLEAR_DEPTH_BUFFER ) flag |= GL_DEPTH_BUFFER_BIT;
249
float r = ((color>>16)&0xFF)/255.0f;
250
float g = ((color>> 8)&0xFF)/255.0f;
251
float b = ((color )&0xFF)/255.0f;
252
float a = ((color>>24)&0xFF)/255.0f;
253
glClearColor(r, g, b, a);
255
glClear(flag); //Clear color buffer and depth buffer
258
void COGLGraphicsContext::UpdateFrame(bool swaponly)
260
status.gFrameCount++;
264
//wglSwapIntervalEXT(0);
267
if (debuggerPauseCount == countToPause)
269
static int iShotNum = 0;
270
// get width, height, allocate buffer to store image
271
int width = windowSetting.uDisplayWidth;
272
int height = windowSetting.uDisplayHeight;
273
printf("Saving debug images: width=%i height=%i\n", width, height);
274
short *buffer = (short *) malloc(((width+3)&~3)*(height+1)*4);
275
glReadBuffer( GL_FRONT );
276
// set up a BMGImage struct
277
struct BMGImageStruct img;
278
memset(&img, 0, sizeof(BMGImageStruct));
280
img.bits = (unsigned char *) buffer;
281
img.bits_per_pixel = 32;
284
img.scan_width = width * 4;
285
// store the RGB color image
287
sprintf(chFilename, "dbg_rgb_%03i.png", iShotNum);
288
glReadPixels(0,0,width,height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
289
WritePNG(chFilename, img);
290
// store the Z buffer
291
sprintf(chFilename, "dbg_Z_%03i.png", iShotNum);
292
glReadPixels(0,0,width,height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, buffer);
293
//img.bits_per_pixel = 16;
294
//img.scan_width = width * 2;
295
WritePNG(chFilename, img);
296
// dump a subset of the Z data
297
for (int y = 0; y < 480; y += 16)
299
for (int x = 0; x < 640; x+= 16)
300
printf("%4hx ", buffer[y*640 + x]);
304
// free memory and get out of here
311
// if emulator defined a render callback function, call it before buffer swap
315
SDL_GL_SwapBuffers();
317
/*if(options.bShowFPS)
319
static unsigned int lastTick=0;
321
unsigned int nowTick = SDL_GetTicks();
323
if(lastTick + 5000 <= nowTick)
326
sprintf(caption, "RiceVideoLinux N64 Plugin %s - %.3f VI/S", MUPEN_VERSION, frames/5.0);
327
SDL_WM_SetCaption(caption, caption);
333
glDepthMask(GL_TRUE);
335
if( !g_curRomInfo.bForceScreenClear )
336
glClear(GL_DEPTH_BUFFER_BIT);
338
needCleanScene = true;
340
status.bScreenIsDrawn = false;
343
bool COGLGraphicsContext::SetFullscreenMode()
345
windowSetting.uDisplayWidth = windowSetting.uFullScreenDisplayWidth;
346
windowSetting.uDisplayHeight = windowSetting.uFullScreenDisplayHeight;
347
windowSetting.statusBarHeightToUse = 0;
348
windowSetting.toolbarHeightToUse = 0;
352
bool COGLGraphicsContext::SetWindowMode()
354
windowSetting.uDisplayWidth = windowSetting.uWindowDisplayWidth;
355
windowSetting.uDisplayHeight = windowSetting.uWindowDisplayHeight;
356
windowSetting.statusBarHeightToUse = windowSetting.statusBarHeight;
357
windowSetting.toolbarHeightToUse = windowSetting.toolbarHeight;
360
int COGLGraphicsContext::ToggleFullscreen()
362
if(SDL_WM_ToggleFullScreen(m_pScreen) == 1)
364
m_bWindowed = 1 - m_bWindowed;
371
return m_bWindowed?0:1;
374
// This is a static function, will be called when the plugin DLL is initialized
375
void COGLGraphicsContext::InitDeviceParameters()
377
status.isVertexShaderEnabled = false; // Disable it for now