Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / GraphicsPlugin.cpp
CommitLineData
22726e4d 1/******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4 *
5 * Copyright (C) 2009 Jon Ring
6 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *****************************************************************************/
22
23#include "GraphicsPlugin.h"
24#include "VI.h" //Video interface
25#include "Memory.h" //Access to memory (RDRAM, Texture Memory)
26#include "OpenGLRenderer.h" //Renderer
27#include "FrameBuffer.h" //Framebuffer
28#include "DisplayListParser.h" //Displaylist parser
29#include "FogManager.h" //Fog
30#include "RSP.h" //Reality Signal Processor
31#include "RDP.h" //Reality Drawing Processor
32#include "GBI.h" //Graphics Binary Interface
33#include "ConfigMap.h" //Configuration
34#include "Logger.h" //Debug logger
35#include "RomDetector.h"
36#include <ctime>
37#ifdef HAVE_GLES
38#include "eglport.h"
39#include <SDL.h>
40#include <SDL_opengles.h>
41#endif
42
43//FrameBuffer framebuffer01;
44//FrameBuffer framebuffer02;
45
46//-----------------------------------------------------------------------------
47//! Constructor
48//-----------------------------------------------------------------------------
49GraphicsPlugin::GraphicsPlugin()
50: m_openGLMgr( OpenGLManager::getSingleton() )
51{
52 m_vi = 0;
53 m_initialized = false;
54 m_updateConfig = false;
55 m_fogManager = 0;
56}
57
58//-----------------------------------------------------------------------------
59//! Destructor
60//-----------------------------------------------------------------------------
61GraphicsPlugin::~GraphicsPlugin()
62{
63 dispose();
64}
65
66//-----------------------------------------------------------------------------
67// Initialize
68//-----------------------------------------------------------------------------
69bool GraphicsPlugin::initialize(GFX_INFO* graphicsInfo)
70{
71 //Initialize video output
72 if (CoreVideo_Init() != M64ERR_SUCCESS)
73 {
74 Logger::getSingleton().printMsg("Could not initialize video.", M64MSG_ERROR);
75 return false;
76 }
77
78 //Save pointer to graphics info
79 m_graphicsInfo = graphicsInfo;
80
81 m_numDListProcessed = 0;
82
83 //Detect what rom it is
84 m_romDetector = &ROMDetector::getSingleton();
85 m_romDetector->initialize( m_graphicsInfo->HEADER );
86#ifdef HAVE_GLES
87 SDL_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, SDL_FULLSCREEN);
88 SDL_ShowCursor(SDL_DISABLE);
89 EGL_Open(m_config->fullscreenWidth, m_config->fullscreenHeight);
90#else
91 if (m_config->multiSampling > 0)
92 {
93 CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1);
94 if (m_config->multiSampling <= 2)
95 CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2);
96 else if (m_config->multiSampling <= 4)
97 CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4);
98 else if (m_config->multiSampling <= 8)
99 CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8);
100 else
101 CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16);
102 }
103
104 if (CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1) != M64ERR_SUCCESS ||
105 CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32) != M64ERR_SUCCESS ||
106 CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 24) != M64ERR_SUCCESS)
107 {
108 Logger::getSingleton().printMsg("Could not set video attributes.", M64MSG_ERROR);
109 return false;
110 }
111
112 if (CoreVideo_SetVideoMode(m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth,
113 m_config->startFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, (m64p_video_flags) 0) != M64ERR_SUCCESS)
114 {
115 Logger::getSingleton().printMsg("Could not set video mode.", M64MSG_ERROR);
116 return false;
117 }
118
119 CoreVideo_SetCaption("Arachnoid");
120#endif
121 //Initialize Video Interface
122 m_vi = new VI();
123 m_vi->calcSize(m_graphicsInfo);
124
125 //Initialize Memory
126 m_memory = new Memory();
127 if ( !m_memory->initialize(m_graphicsInfo->RDRAM, m_graphicsInfo->DMEM) )
128 {
129 return false;
130 }
131
132 m_displayListParser = new DisplayListParser();
133 m_displayListParser->initialize(&m_rsp, &m_rdp, &m_gbi, m_memory);
134
135 //Init OpenGL
136 if ( !m_openGLMgr.initialize(m_config->startFullscreen, m_config->fullscreenWidth, m_config->fullscreenHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate, true, false) )
137 {
138 Logger::getSingleton().printMsg("Unable to initialize OpenGL", M64MSG_ERROR);
139 return false;
140 }
141
142
143 m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
144
145 //Initialize Fog Manager
146 m_fogManager = new FogManager();
147 m_fogManager->initialize();
148
149
150
151 //Initialize Texture Cache
152 //! @todo Not "hardcode" TextureBitDepth.
153 m_textureCache.initialize(&m_rsp, &m_rdp, m_memory, 16);
154 m_textureCache.setMipmap( m_config->mipmapping );
155
156 //Initialize OpenGL Renderer
157 if ( !OpenGLRenderer::getSingleton().initialize(&m_rsp, &m_rdp, &m_textureCache, m_vi, m_fogManager) )
158 {
159 Logger::getSingleton().printMsg("Unable to initialize OpenGL Renderer", M64MSG_ERROR);
160 return false;
161 }
162
163 //Initialize Processors
164 m_rdp.initialize(m_graphicsInfo, &m_rsp, m_memory, &m_gbi, &m_textureCache, m_vi, m_displayListParser, m_fogManager);
165 m_rsp.initialize(m_graphicsInfo, &m_rdp, m_memory, m_vi, m_displayListParser, m_fogManager);
166 m_gbi.initialize(&m_rsp, &m_rdp, m_memory, m_displayListParser);
167
168
169 //Set Background color
170 m_openGLMgr.setClearColor(0.0f, 0.0f, 0.0f);
171 m_openGLMgr.setLighting(false);
172 glDisable(GL_LIGHTING);
173 m_openGLMgr.setCullMode(false, true);
174 m_openGLMgr.setWireFrame(m_config->wireframe);
175
176 //Initialize framebuffer
177 //framebuffer01.initialize(width, height);
178 // framebuffer02.initialize(width, height);
179
180 m_initialized = true;
181 return true;
182}
183
184//-----------------------------------------------------------------------------
185// Dispose
186//-----------------------------------------------------------------------------
187void GraphicsPlugin::dispose()
188{
189 //Dispose of Textures
190 m_textureCache.dispose();
191
192 //Dispose of member objects
193 if ( m_vi ) { delete m_vi; m_vi = 0; }
194 if ( m_memory ) { delete m_memory; m_memory = 0; }
195 if ( m_displayListParser ) { delete m_displayListParser; m_displayListParser = 0; }
196 if ( m_fogManager ) { delete m_fogManager; m_fogManager = 0; }
197
198 m_gbi.dispose();
199 m_rdp.dispose();
200 m_rsp.dispose();
201
202 //Dispose of OpenGL
203 //framebuffer01.dispose();
204 // framebuffer02.dispose();
205 m_openGLMgr.dispose();
206
207 if (m_initialized)
208#ifdef HAVE_GLES
209 {
210 EGL_Close();
211 SDL_Quit(); // *SEB* *TODO* Close Subsystem only?
212 }
213#else
214 CoreVideo_Quit();
215#endif
216
217 m_initialized = false;
218}
219
220void renderMotionBlur()
221{
222 ///glPushMatrix();
223
224 glDisable(GL_DEPTH_TEST);
225 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
226 glEnable(GL_BLEND);
227 glColor4f(1, 1, 1, 0.9f); //Alpha blending
228
229// framebuffer01.render2();
230
231 glColor4f(1, 1, 1, 1.0f); //Alpha blending
232 glEnable(GL_DEPTH_TEST);
233 glDisable(GL_BLEND);
234
235 //glPopMatrix();
236}
237
238bool animate(int frameRate)
239{
240 static clock_t lastTime;
241 clock_t currentTime = clock() * 1000 / CLOCKS_PER_SEC;
242 clock_t elapsedTime = currentTime - lastTime;
243 if (elapsedTime > ((clock_t)1000 / frameRate))
244 {
245 lastTime = currentTime;
246 return true;
247 }
248 return false;
249
250#if 0
251 //Todo: test against new version
252 static float lastTime = 0.0f;
253 float elapsedTime = 0.0;
254 float currentTime = GetTickCount() * 0.001f;
255 elapsedTime = currentTime - lastTime;
256
257 if( elapsedTime > (1.0f / frameRate) )
258 {
259 lastTime = currentTime;
260 return true;
261 }
262
263 return false;
264#endif
265
266}
267
268void renderQuad()
269{
270 static float dt = 0;
271 dt += 0.2f;
272
273 //glDisable(GL_CULL_FACE);
274 glMatrixMode(GL_MODELVIEW);
275 glPushMatrix();
276 // glRotatef(dt, 0, 1, 0);
277 {
278#ifdef HAVE_GLES
279//*SEB* *TODO*
280#else
281 glBegin(GL_QUADS);
282 {
283 glColor3f(1,0,0); glVertex3f(-1,-1,0);
284 glColor3f(1,1,0); glVertex3f( 1,-1,0);
285 glColor3f(0,1,1); glVertex3f( 1, 1,0);
286 glColor3f(0,0,1); glVertex3f(-1, 1,0);
287 }
288 glEnd();
289#endif
290 }
291 glPopMatrix();
292}
293
294void renderRedBox(float x, float y, float z, float width, float height, float length)
295{
296 static float dt = 0;
297 dt += 10.6f;
298 glRotatef(dt, 1,1,1);
299 x = x - width / 2;
300 y = y - height / 2;
301 z = z - length / 2;
302#ifdef HAVE_GLES
303//*SEB* *TODO*
304#else
305 glBegin(GL_QUADS);
306 glColor3f(1,0,0);
307 glVertex3f(x, y, z);
308 glVertex3f(x, y + height, z);
309 glVertex3f(x + width, y + height, z);
310 glVertex3f(x + width, y, z);
311 glVertex3f(x, y, z + length);
312 glVertex3f(x, y + height, z + length);
313 glVertex3f(x + width, y + height, z + length);
314 glVertex3f(x + width, y, z + length);
315 glVertex3f(x, y, z);
316 glVertex3f(x, y, z + length);
317 glVertex3f(x + width, y, z + length);
318 glVertex3f(x + width, y, z);
319 glVertex3f(x, y + height, z);
320 glVertex3f(x, y + height, z + length);
321 glVertex3f(x + width, y + height, z + length);
322 glVertex3f(x + width, y + height, z);
323 glVertex3f(x, y, z);
324 glVertex3f(x, y, z + length);
325 glVertex3f(x, y + height, z + length);
326 glVertex3f(x, y + height, z);
327 glVertex3f(x + width, y, z);
328 glVertex3f(x + width, y, z + length);
329 glVertex3f(x + width, y + height, z + length);
330 glVertex3f(x + width, y + height, z);
331 glColor3f(1,1,1);
332 glEnd();
333#endif
334}
335
336//-----------------------------------------------------------------------------
337// ProcessDisplayList
338//-----------------------------------------------------------------------------
339void GraphicsPlugin::processDisplayList()
340{
341 if ( (m_numDListProcessed == 1 && m_romDetector->getClearType() == CT_AFTER_ONE_DISPLAY_LIST) ||
342 (m_numDListProcessed == 2 && m_romDetector->getClearType() == CT_AFTER_TWO_DISPLAY_LIST) ||
343 (m_numDListProcessed == 3 && m_romDetector->getClearType() == CT_AFTER_THREE_DISPLAY_LIST) )
344 {
345 bool scissors = OpenGLManager::getSingleton().getScissorEnabled();
346 OpenGLManager::getSingleton().setScissorEnabled(false);
347 glClear(GL_COLOR_BUFFER_BIT);
348 m_numDListProcessed = 0;
349 OpenGLManager::getSingleton().setScissorEnabled(scissors);
350 }
351
352 //Update Config?
353 if ( m_updateConfig )
354 {
355 m_vi->calcSize(m_graphicsInfo);
356 m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
357 OpenGLManager::getSingleton().setViewport(0, 0, m_config->windowWidth, m_config->windowHeight);
358 m_openGLMgr.setWireFrame( m_config->wireframe );
359 _setTextureCacheSize( m_config->textureCacheSize );
360 m_updateConfig = false;
361
362 //if ( OpenGLManager::getSingleton().getFullscreen() )
363 //{
364 // //Initialize framebuffer
365 // FrameBuffer::getSingleton().dispose();
366 // FrameBuffer::getSingleton().initialize(m_config->fullscreenWidth, m_config->fullscreenHeight);
367 //}
368 //else
369 //{
370 // //Initialize framebuffer
371 // FrameBuffer::getSingleton().dispose();
372 // FrameBuffer::getSingleton().initialize(m_config->windowWidth, m_config->windowHeight);
373 //}
374
375
376 }
377
378 //Get Video Interface Size
379 m_vi->calcSize(m_graphicsInfo);
380 m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
381 OpenGLManager::getSingleton().setForceDisableCulling( ROMDetector::getSingleton().getDisableFaceCulling() );
382
383 //Render Scene
384 OpenGLManager::getSingleton().beginRendering();
385 OpenGLManager::getSingleton().setTextureing2D(true);
386 glEnable(GL_DEPTH_TEST);
387 {
388 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
389 m_rsp.reset();
390 m_rdp.reset();
391 m_openGLMgr.setCullMode(false, true);
392 m_displayListParser->processDisplayList();
393 }
394
395 //Clear Screen?
396 m_numDListProcessed++;
397
398 //glFlush();
399// OpenGLManager::getSingleton().endRendering();
400 OpenGLManager::getSingleton().setDrawFlag();
401 //Take screenshot?
402}
403
404//-----------------------------------------------------------------------------
405// Update Screen
406//-----------------------------------------------------------------------------
407void GraphicsPlugin::drawScreen()
408{
409 OpenGLManager::getSingleton().endRendering();
410}
411
412void GraphicsPlugin::setDrawScreenSignal()
413{
414 m_rdp.signalUpdate();
415}
416
417//-----------------------------------------------------------------------------
418// Video Interface Status Changed
419//-----------------------------------------------------------------------------
420void GraphicsPlugin::viStatusChanged()
421{
422 //Get new VI Size
423 m_vi->calcSize( m_graphicsInfo );
424
425 //Re Calculate Scale
426 m_openGLMgr.calcViewScale(m_vi->getWidth(), m_vi->getHeight());
427}
428
429//-----------------------------------------------------------------------------
430// Toggle Fullscreen
431//-----------------------------------------------------------------------------
432void GraphicsPlugin::toggleFullscreen()
433{
434 if ( m_initialized )
435 {
436 CoreVideo_ToggleFullScreen();
437 }
438}
439
440//-----------------------------------------------------------------------------
441// Take Screenshot
442//-----------------------------------------------------------------------------
443void GraphicsPlugin::takeScreenshot(void *dest, int *width, int *height, int front)
444{
445 *width = m_config->windowWidth;
446 *height = m_config->windowHeight;
447 if (dest)
448 {
449#ifndef HAVE_GLES
450 if (front)
451 glReadBuffer(GL_FRONT);
452 else
453 glReadBuffer(GL_BACK);
454#endif
455 glReadPixels(0, 0, *width, *height, GL_RGB, GL_UNSIGNED_BYTE, dest);
456 }
457}
458
459//-----------------------------------------------------------------------------
460// Update Configuration
461//-----------------------------------------------------------------------------
462void GraphicsPlugin::updateConfig()
463{
464 m_updateConfig = true;
465
466 //For project 64, Give config dialog time to close before continueing
467#ifdef WIN32
468 Sleep(300);
469#endif
470 //Resize Window
471 _setWindowMode(m_config->windowWidth, m_config->windowHeight);
472
473 //Reinitialize OpenGL
474 OpenGLManager::getSingleton().resize(m_config->windowWidth, m_config->windowHeight, m_config->fullscreenBitDepth, m_config->fullscreenRefreshRate);
475}
476
477//-----------------------------------------------------------------------------
478// Set Window Mode
479//-----------------------------------------------------------------------------
480void GraphicsPlugin::_setWindowMode(int width, int height)
481{
482 if ( m_initialized )
483 {
484 //TODO: is this function needed?
485 //m_windowMgr->resizeWindow(width, height);
486 }
487}
488
489//-----------------------------------------------------------------------------
490// Set Texture Cache Size
491//-----------------------------------------------------------------------------
492void GraphicsPlugin::_setTextureCacheSize(int sizeInBytes)
493{
494
495}